【问题标题】:Not getting correct port number by GetExtendedTcpTable in delphi 7delphi 7中的GetExtendedTcpTable没有得到正确的端口号
【发布时间】:2011-07-16 21:13:54
【问题描述】:

我已经实现了以下代码,用于通过函数 getTCPExtendedTable 获取 TCP 信息:

    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”等答案。请帮忙。

提前致谢

【问题讨论】:

    标签: delphi


    【解决方案1】:

    端口号以网络字节顺序给出。网络字节顺序是大端的,所以你必须颠倒字节的顺序才能理解它。

    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;
      

      这应该给出正确的输出

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-04
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        • 2017-01-03
        • 1970-01-01
        相关资源
        最近更新 更多