根据使用的套接字终止Delphi应用程序 [英] Kill a Delphi app based on which socket it is using
问题描述
让我们假设您有一个可以打开套接字端口进行通信的应用程序.我该如何仅通过知道其端口来获取该应用程序的路径?
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.
首先,您必须检查此函数返回的记录,并检查dwLocalPort
或dwRemotePort
(取决于您需要检查的端口),然后才能获取检查dwOwningPid
字段的应用程序的pid.并使用Windows API函数(例如 GetModuleFileNameEx
first you must inspect the records returned by this function, and check the dwLocalPort
or 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屋!