delphi - 根据正在使用的套接字杀死 Delphi 应用程序

标签 delphi sockets ipc

假设您有一个应用程序打开套接字端口以进行通信。如何仅通过知道该应用程序的端口即可获取该应用程序的路径?

我想做 netstat -b 所做的事情。它列出了所有打开的套接字端口以及打开套接字的应用程序。

我使用的是delphi 2010。 通过知道哪个应用程序打开了哪个端口,我可以杀死该应用程序。

请注意,我需要一个 delphi 代码,而不是 Dos 命令或如何使用 netstat 的说明。

最佳答案

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

首先你必须检查该函数返回的记录,并检查dwLocalPortdwRemotePort(取决于你需要检查的端口),然后你可以得到应用程序的 pid 检查 dwOwningPid 字段并使用 Windows API 函数(如 GetModuleFileNameEx )解析 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.

关于delphi - 根据正在使用的套接字杀死 Delphi 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5351599/

相关文章:

multithreading - Delphi和线程: “System Error. Code: 1400. Invalid window handle”

delphi - 如何在 Delphi TStringList 中更快地搜索名称/值对?

Delphi RTTI TVirtualMethodInterceptor.Create不支持具有重载虚方法的类

python - 为什么发送字符串并关闭套接字后会有 TCP RST 数据包

winapi - 将数据从 Windows Hook 传递到另一个进程的最佳方法是什么?

使用动态成员创建全局结构

c++ - IPC共享内存是否从堆中获取内存?

delphi - 在 TClientDataSet 中使用 Locate 时是否必须使用 Disable/EnableControls?

c - 如果我使用 select() 服务器编写一个对等 2 个对等应用程序而不使用 fork()、线程、共享内存、信号量,这样可以吗?

Java套接字超时: Broken pipe