让我们假设你有一个应用程序打开一个套接字端口用于通信目的.
如何通过了解其端口才能获得此应用的路径?
我想做netstat -b做的事情.它列出了所有打开的套接字端口和打开套接字的应用程序.
我正在使用delphi 2010.
通过知道应用程序打开了我能够杀死应用程序的端口.
请注意,我需要一个delphi代码,而不是Dos命令或如何使用netstat的说明.
如何通过了解其端口才能获得此应用的路径?
我想做netstat -b做的事情.它列出了所有打开的套接字端口和打开套接字的应用程序.
我正在使用delphi 2010.
通过知道应用程序打开了我能够杀死应用程序的端口.
请注意,我需要一个delphi代码,而不是Dos命令或如何使用netstat的说明.
解决方法
Rafael,您可以使用
GetExtendedTcpTable
函数,此函数检索包含可用TCP连接列表的表.
首先,您必须检查此函数返回的记录,并检查dwLocalPortor dwRemotePort(取决于您需要检查的端口),然后您可以获取应用程序的pid检查dwOwningPid字段并使用Windows api函数解析exe名称像GetModuleFileNameEx
检查此示例应用程序,它显示所有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,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,AF_INET,TCP_TABLE_OWNER_PID_ALL,0); if Error <> ERROR_INSUFFICIENT_BUFFER then Exit; GetMem(FExtendedTcpTable,TableSize); try if GetExtendedTcpTable(FExtendedTcpTable,TRUE,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.