开发者

Kill a Delphi app based on which socket it is using

开发者 https://www.devze.com 2023-02-18 10:57 出处:网络
Lets assume you have a app that opens a socket port for communication purposes. How can I get the path of this app only by knowing its port?

Lets assume you have a app that opens a socket port for communication purposes. How can I get the path of this app only by knowing its port?

I want to do what netstat -b does. It lists all socket ports opened and the app that opened the socket.

I am using delphi 2010. By knowing which app opened which开发者_StackOverflow中文版 port I am able to kill the app.

Note that I need a delphi code, not an Dos command or an explanation of how to use netstat.


Rafael, you can use the GetExtendedTcpTable function, this function retrieves a table that contains a list of TCP connections availables.

first you must inspect the records returned by this function, and check the dwLocalPortor dwRemotePort (depending of what port your need to check), then you can get the pid of the application checking the dwOwningPid field and resolve the exe name using a windows api function like GetModuleFileNameEx

Check this sample application which show all tcp connections like netstat. you can modify this sample to fit with your requirements.

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.


You can use IP Helper Component of Magenta Systems. It is free and also has very good example


For correct number of port you must using function WinSock

ntohs(FExtendedTcpTable.Table[i].dwLocalPort)
0

精彩评论

暂无评论...
验证码 换一张
取 消