通过套接字端口获取应用路径

时间:2011-03-18 11:53:23

标签: delphi sockets ipc

让我们假设您有一个应用程序打开套接字端口以实现通信目的。 如何通过了解其端口来获取此应用的路径? 我想做netstat -b做的事情。它列出了所有打开的套接字端口和打开套接字的应用程序。 我正在使用delphi 2010。 通过知道应用程序打开了我能够杀死应用程序的端口。 请注意,我需要一个delphi代码,而不是Dos命令或如何使用netstat的解释。

3 个答案:

答案 0 :(得分:9)

Rafael,您可以使用GetExtendedTcpTable函数,此函数检索包含可用TCP连接列表的表。

首先你必须检查这个函数返回的记录,并检查dwLocalPortdwRemotePort(取决于你需要检查的端口),然后你可以得到应用程序的pid检查dwOwningPid字段并使用类似GetModuleFileNameEx

的Windows api函数解析exe名称

检查此示例应用程序,该应用程序显示所有tcp连接,如netstat。您可以修改此示例以符合您的要求。

uses
      PsAPI,
      WinSock,
      Windows,
      SysUtils;

    const
       ANY_SIZE = 1;
       iphlpapi = 'iphlpapi.dll';
       TCP_TABLE_OWNER_PID_ALL = 5;

       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');

    type
       TCP_TABLE_CLASS = Integer;

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


      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;

    var
       GetExtendedTcpTable:function  (pTcpTable: Pointer; dwSize: PDWORD; bOrder: BOOL; lAf: ULONG; TableClass: TCP_TABLE_CLASS; Reserved: ULONG): DWord; stdcall;




    function GetPathPID(PID: DWORD): string;
    var
      Handle: THandle;
    begin
      Result := '';
      Handle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, PID);
      if Handle <> 0 then
        try
          SetLength(Result, MAX_PATH);
            if GetModuleFileNameEx(Handle, 0, PChar(Result), MAX_PATH) > 0 then
              SetLength(Result, StrLen(PChar(Result)))
            else
              Result := '';
        finally
          CloseHandle(Handle);
        end;
    end;


    procedure ShowCurrentTCPConnections;
    var
       Error        : DWORD;
       TableSize    : DWORD;
       i            : integer;
       IpAddress    : in_addr;
       RemoteIp     : string;
       LocalIp      : string;
       FExtendedTcpTable : PMIB_TCPTABLE_OWNER_PID;
    begin
      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
          for i := 0 to FExtendedTcpTable.dwNumEntries - 1 do
          if {(FExtendedTcpTable.Table[i].dwOwningPid=Pid) and} (FExtendedTcpTable.Table[i].dwRemoteAddr<>0) then //here you can check the particular port
          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));
             Writeln(GetPathPID(FExtendedTcpTable.Table[i].dwOwningPid));
             Writeln(Format('%-16s %-6d %-16s %-6d %s',[LocalIp,FExtendedTcpTable.Table[i].dwLocalPort,RemoteIp,FExtendedTcpTable.Table[i].dwRemotePort,MIB_TCP_STATE[FExtendedTcpTable.Table[i].dwState]]));
          end;
      finally
         FreeMem(FExtendedTcpTable);
      end;
    end;

    var
       libHandle : THandle;
    begin
      try
        ReportMemoryLeaksOnShutdown:=DebugHook<>0;
        libHandle           := LoadLibrary(iphlpapi);
        GetExtendedTcpTable := GetProcAddress(libHandle, 'GetExtendedTcpTable');
        ShowCurrentTCPConnections;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;

      readln;
    end.

答案 1 :(得分:0)

您可以使用IP Helper Component of Magenta Systems。 它是免费的,也非常好example

答案 2 :(得分:0)

要获得正确的端口数,必须使用WinSock函数

ntohs(FExtendedTcpTable.Table[i].dwLocalPort)