2011-07-16 59 views
3

我已經實現下面的代碼由功能getTCPExtendedTable得到TCP信息:在delphi沒有得到正確的端口號由GetExtendedTcpTable 7

const 
ANY_SIZE = 1; 
iphlpapi = 'iphlpapi.dll'; //For using the DLL 
TCP_TABLE_OWNER_PID_ALL = 5; 
{States of the Connections} 
MIB_TCP_STATE: 
array[1..12] of string = ('CLOSED', 'LISTEN', 'SYN-SENT ','SYN-RECEIVED', 'ESTABLISHED', 'FIN-WAIT-1', 
          'FIN-WAIT-2', 'CLOSE-WAIT', 'CLOSING','LAST-ACK', 'TIME- WAIT', 'delete TCB'); 
    {record of type MIB_TCPROW: 
    typedef struct _MIB_TCPROW 
    { 
DWORD dwState; 
DWORD dwLocalAddr; 
DWORD dwLocalPort; 
DWORD dwRemoteAddr; 
DWORD dwRemotePort; 
    }//MIB_TCPROW, *PMIB_TCPROW; 


    type 
{The type of the TCP table structure to retrieve. 
This parameter can be one of the values from the TCP_TABLE_CLASS enumeration. } 
TCP_TABLE_CLASS = Integer; 

PMibTcpRowOwnerPid = ^TMibTcpRowOwnerPid; 
TMibTcpRowOwnerPid = packed record 
    dwState  : DWORD; 
    dwLocalAddr : DWORD; 
    dwLocalPort : DWORD; 
    dwRemoteAddr: DWORD; 
    dwRemotePort: DWORD; 
    dwOwningPid : DWORD; 
    end; 

    {record of type MIB_TCPTABLE: 
    typedef struct _MIB_TCPTABLE 
    { 
     DWORD dwNumEntries; 
MIB_TCPROW table[ANY_SIZE]; 
    } //MIB_TCPTABLE, *PMIB_TCPTABLE 

     PMIB_TCPTABLE_OWNER_PID = ^MIB_TCPTABLE_OWNER_PID; 
     MIB_TCPTABLE_OWNER_PID = packed record 
dwNumEntries: DWord; 
table: array [0..ANY_SIZE - 1] OF TMibTcpRowOwnerPid; 
end; 

    //Defintion 

    GetExtendedTcpTable:function (pTcpTable: Pointer; dwSize: PDWORD; bOrder: BOOL; lAf: ULONG; TableClass: TCP_TABLE_CLASS; Reserved: ULONG): DWord; stdcall; 
    procedure TFmainViewTCP.ShowCurrentTCPConnections; 



    var 
    Error  : DWORD; 
    TableSize : DWORD; 
    i   : integer; 
    IpAddress : in_addr; 
    RemoteIp  : string; 
    LocalIp  : string; 
    ProcName:string; 
    FExtendedTcpTable : PMIB_TCPTABLE_OWNER_PID; 
    begin 
i:=0; 
TableSize := 0; 
Error := GetExtendedTcpTable(nil, @TableSize, False,AF_INET, TCP_TABLE_OWNER_PID_ALL, 0); 

if Error <> ERROR_INSUFFICIENT_BUFFER then 
Exit; 

    GetMem(FExtendedTcpTable, TableSize); 
    try 
    if GetExtendedTcpTable(FExtendedTcpTable, @TableSize, TRUE,AF_INET,TCP_TABLE_OWNER_PID_ALL, 0) = NO_ERROR then 
    begin 
    for i := 0 to FExtendedTcpTable.dwNumEntries - 1 do 

    begin 
     IpAddress.s_addr := FExtendedTcpTable.Table[i].dwRemoteAddr; 
     RemoteIp := string(inet_ntoa(IpAddress)); 
     IpAddress.s_addr := FExtendedTcpTable.Table[i].dwLocalAddr; 
     LocalIp   := string(inet_ntoa(IpAddress)); 

     Memo1.Lines.Add(IntToStr(FExtendedTcpTable.Table[i].dwOwningPid)); 
     Memo1.Lines.Add(IntToStr(Lo(FExtendedTcpTable.Table[i].dwLocalPort))); 

     end; //for 
    end; //if 
    finally 
     FreeMem(FExtendedTcpTable); 
    end; 
    end; 

的問題是,所顯示的端口號,如「34560」,而通過netstat可以看到真正的端口號是'135'。需要進行哪些更改才能看到正確的端口號?

我讀到我們應該只顯示dwLocalPort的低16字節。我用Lo()函數做到了。我得到了'0','8'等答案,請幫助。

由於提前

回答

3

的端口號在網絡字節順序給出。網絡字節順序是大端,所以你必須顛倒字節的順序來理解它。

MIB_TCPROW_OWNER_PID的文檔包含此重要的一點。

dwLocalPort和dwRemotePort成員處於網絡字節順序。爲了使用dwLocalPort或dwRemotePort成員,可能需要Windows套接字或類似函數中的ntohs或inet_ntoa函數。

只需通過端口號ntohs(),他們將再次感覺到你。例如:

Memo1.Lines.Add(IntToStr(ntohs(FExtendedTcpTable.Table[i].dwLocalPort))); 
2

該函數返回需要轉換爲真正的端口號原始的端口號, 這可以通過

function ConvertRawPortToRealPort(RawPort : DWORD) : DWORD; 
begin 
    Result := (RawPort div 256) + (RawPort mod 256) * 256; 
end; 

做這應該給正確的輸出