根据使用的套接字终止Delphi应用程序 [英] Kill a Delphi app based on which socket it is using

查看:81
本文介绍了根据使用的套接字终止Delphi应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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?

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

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

我正在使用delphi 2010. 通过知道哪个应用程序打开了哪个端口,我可以终止该应用程序.

I am using delphi 2010. By knowing which app opened which port I am able to kill the app.

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

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.

首先,您必须检查此函数返回的记录,并检查dwLocalPortdwRemotePort(取决于您需要检查的端口),然后才能获取检查dwOwningPid字段的应用程序的pid.并使用Windows API函数(例如 GetModuleFileNameEx

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

检查此示例应用程序,其中显示了所有类似netstat的tcp连接.您可以修改此示例以使其符合您的要求.

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.

这篇关于根据使用的套接字终止Delphi应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆