![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Здравствуйте! как зная PID вывести все соединение программы?
Код:
function RunCommandAndCaptureOutput(const CmdLine: string; OutputLines: TStrings): Boolean; var Security: TSecurityAttributes; ReadPipe, WritePipe: THandle; StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; Buffer: array[0..255] of Byte; BytesRead: DWORD; S: string; begin Result := False; Security.nLength := SizeOf(TSecurityAttributes); Security.bInheritHandle := True; Security.lpSecurityDescriptor := nil; if not CreatePipe(ReadPipe, WritePipe, @Security, 0) then Exit; try ZeroMemory(@StartupInfo, SizeOf(StartupInfo)); StartupInfo.cb := SizeOf(StartupInfo); StartupInfo.hStdOutput := WritePipe; StartupInfo.hStdError := WritePipe; StartupInfo.dwFlags := STARTF_USESTDHANDLES; if not CreateProcess(nil, PChar(CmdLine), nil, nil, True, CREATE_NO_WINDOW, nil, nil, StartupInfo, ProcessInfo) then Exit; CloseHandle(WritePipe); S := ''; repeat BytesRead := 0; ZeroMemory(@Buffer, SizeOf(Buffer)); if ReadFile(ReadPipe, Buffer, SizeOf(Buffer), BytesRead, nil) then begin if BytesRead > 0 then begin S := S + String(PAnsiChar(@Buffer[0])); end; end; until BytesRead = 0; WaitForSingleObject(ProcessInfo.hProcess, INFINITE); CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); // Разделяем строки OutputLines.Text := S; Result := True; finally CloseHandle(ReadPipe); end; end; Код:
procedure GetIPsByPID(PID: DWORD; Memo: TMemo); var OutputLines: TStringList; Line: string; SearchStr: string; P: Integer; begin Memo.Clear; // Запускаем netstat OutputLines := TStringList.Create; try if not RunCommandAndCaptureOutput('netstat -ano', OutputLines) then begin Memo.Lines.Add('Ошибка запуска netstat'); Exit; end; // Ищем строки с нужным PID for Line in OutputLines do begin SearchStr := ' ' + IntToStr(PID) + ' '; if Pos(SearchStr, Line) > 0 then begin // В строке ищем IP-адреса // Обычно строки вида: TCP 192.168.1.2:12345 93.184.216.34:80 ESTABLISHED // Разделяем по пробелам // Можно парсить вручную или искать IP-адреса Memo.Lines.Add(Line); end; end; finally OutputLines.Free; end; end; Код:
GetIPsByPID(12156, Memo1); ![]() |
#2
|
|||
|
|||
![]() В предыдущем вопросе (https://delphisources.ru/forum/showt...077#post159077) я оставил константу TCP_TABLE_OWNER_PID_ALL при вызове GetExtendedTcpTable. В этом случае в ответе будет также заполнено поле dwOwningPid - там как раз PID процесса, установившего соединение. Соответсвенно, получи PID и просто отфильтруй нужные соединения.
|
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
leon2009 (05.07.2025)
|
#3
|
|||
|
|||
![]() добавил: PID :=1234;
if dwOwningPid = PID then может что то упустил ![]() Код:
procedure TConnectionListener.ListOpenTCPConnections; var TcpTable: PMIB_TCPTABLE_OWNER_PID; TableSize,PID: DWORD; i: Integer; begin PID :=1234;// strtoint(form1.edit1.text); TableSize := 0; // First call to get the required buffer size GetExtendedTcpTable(nil, TableSize, True, AF_INET, {TCP_TABLE_BASIC_CONNECTIONS} TCP_TABLE_OWNER_PID_ALL, 0); // Allocate memory for the table GetMem(TcpTable, TableSize); try // Retrieve the TCP table if GetExtendedTcpTable(TcpTable, TableSize, True, AF_INET, {TCP_TABLE_BASIC_CONNECTIONS} TCP_TABLE_OWNER_PID_ALL, 0) = NO_ERROR then begin SetLength(FIpTable,TcpTable.dwNumEntries); for i := 0 to TcpTable.dwNumEntries - 1 do begin with TcpTable.Table[i] do begin if dwOwningPid = PID then begin FIpTable[i].LocalAddr := Format('%d.%d.%d.%d:%d', [ dwLocalAddr and $FF, (dwLocalAddr shr 8) and $FF, (dwLocalAddr shr 16) and $FF, (dwLocalAddr shr 24) and $FF, ntohs(dwLocalPort) ]); FIpTable[i].RemoteAddr := Format('%d.%d.%d.%d:%d', [ dwRemoteAddr and $FF, (dwRemoteAddr shr 8) and $FF, (dwRemoteAddr shr 16) and $FF, (dwRemoteAddr shr 24) and $FF, ntohs(dwRemotePort) ]); end; end; end; end else Begin SetLength(FIpTable,1); FIpTable[0].LocalAddr := 'Error'; FIpTable[0].RemoteAddr := 'Error'; End; finally FreeMem(TcpTable); end; end; |
#4
|
|||
|
|||
![]() вот что выдает
Цитата:
|
#5
|
|||
|
|||
![]() 1. Еще раз - фильтровать лучше на "клиентской" стороне, т.е. там, где ты выводишь.
2. надо посмотреть, может PID тоже надо конвертировать с помощью ntohs 3. Ну и что такого, открыт листенер на 135 порт, но никто туда не подключался еще, хотя конечно 0.0.0.0 смотрится странно. |
#6
|
|||
|
|||
![]() Код:
GetExtendedTcpTable(nil, TableSize, True, AF_INET, TCP_TABLE_BASIC_CONNECTIONS {TCP_TABLE_OWNER_PID_ALL}, 0); if GetExtendedTcpTable(TcpTable, TableSize, True, AF_INET, TCP_TABLE_BASIC_CONNECTIONS {TCP_TABLE_OWNER_PID_ALL}, 0) = NO_ERROR then Код:
FIpTable[i].LocalAddr := Format('%d.%d.%d.%d:%d:PID:%d', [ dwLocalAddr and $FF, (dwLocalAddr shr 8) and $FF, (dwLocalAddr shr 16) and $FF, (dwLocalAddr shr 24) and $FF, ntohs(dwLocalPort), dwOwningPid ]); FIpTable[i].RemoteAddr := Format('%d.%d.%d.%d:%d:PID:%d', [ dwRemoteAddr and $FF, (dwRemoteAddr shr 8) and $FF, (dwRemoteAddr shr 16) and $FF, (dwRemoteAddr shr 24) and $FF, ntohs(dwRemotePort) , dwOwningPid ]); Код:
begin IpTableLocker.Enter; Memo1.Lines.BeginUpdate; Try Memo1.Lines.Clear; for I := 0 to FThread.Count-1 do Memo1.Lines.Add(Format('%s <=> %s',[FThread.IpTable[i].LocalAddr,FThread.IpTable[i].RemoteAddr,FThread.IpTable[i].PidAddr])); Finally Memo1.Lines.EndUpdate; IpTableLocker.Leave; End; Код:
if FThread.IpTable[i].PidAddr=1111 then Memo1.Lines.Add(Format('%s <=> %s',[FThread.IpTable[i].LocalAddr,FThread.IpTable[i].RemoteAddr])); Последний раз редактировалось leon2009, 07.07.2025 в 20:47. |
#7
|
|||
|
|||
![]() 0.0.0.0 выводил потому что
Код:
TCP_TABLE_BASIC_CONNECTIONS {TCP_TABLE_OWNER_PID_ALL} Код:
{TCP_TABLE_BASIC_CONNECTIONS} TCP_TABLE_OWNER_PID_ALL |
#8
|
|||
|
|||
![]() я не могу справиться
![]() ставишь это: Код:
TCP_TABLE_OWNER_PID_ALL ставишь Код:
TCP_TABLE_BASIC_CONNECTIONS и пустые результаты <=> т.е. соединений много но почему <=> они пустые |
#9
|
|||
|
|||
![]() пустые - ты if свой убрал?
Код:
// вот этот: if dwOwningPid = PID then begin |
#10
|
|||
|
|||
![]() да я его убрал: результат будет одинаковый:
Цитата:
![]() как я понимаю, есть подключение: 1) По локальной сети WAN Miniport = 0.0.0.0 который готов принимать,,,, 2) WANMiniport = 0.0.0.0 и Ethernet Realtec PCIe Family = 192.168.1.0 = Может из за этого выдает пустые результаты ? ![]() |
#11
|
|||
|
|||
![]() Не знаю, у меня работает.
Без фильтра: Цитата:
С фильтром (18004): Цитата:
Поток: Код:
unit Unit2; interface uses Windows, System.Classes, System.SyncObjs; type TIpTableItem = record LocalAddr : String; RemoteAddr : String; pid : Cardinal; end; TConnectionListener = class(TThread) private { Private declarations } FIpTable : Array Of TIpTableItem; function GetItem(Index: Integer): TIpTableItem; function GetCount: Integer; procedure ListOpenTCPConnections; protected procedure Execute; override; public property Count : Integer read GetCount; property IpTable[Index : Integer] : TIpTableItem read GetItem; end; var IpTableLocker : TCriticalSection; implementation uses IpHlpApi, TlHelp32, WinSock, SysUtils; const TCP_TABLE_BASIC_CONNECTIONS = 1; // Table class for basic TCP connections TCP_TABLE_OWNER_PID_ALL = 5; // Table class for all TCP connections with PIDs AF_INET = 2; // IPv4 AF_INET6 = 23; // IPv6 type MIB_TCPROW_OWNER_PID = 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 = record dwNumEntries: DWORD; table: array[0..0] of MIB_TCPROW_OWNER_PID; end; function GetExtendedTcpTable(pTcpTable: Pointer; var pdwSize: DWORD; bOrder: BOOL; ulAf: ULONG; TableClass: DWORD; Reserved: ULONG): DWORD; stdcall; external 'iphlpapi.dll'; { TConnectionListener } procedure TConnectionListener.Execute; begin While Not Terminated Do Begin IpTableLocker.Enter; Try ListOpenTCPConnections; Finally IpTableLocker.Leave; End; Sleep(500); End; end; procedure TConnectionListener.ListOpenTCPConnections; var TcpTable: PMIB_TCPTABLE_OWNER_PID; TableSize: DWORD; i: Integer; begin TableSize := 0; // First call to get the required buffer size GetExtendedTcpTable(nil, TableSize, True, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0); // Allocate memory for the table GetMem(TcpTable, TableSize); try // Retrieve the TCP table if GetExtendedTcpTable(TcpTable, TableSize, True, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0) = NO_ERROR then begin SetLength(FIpTable,TcpTable.dwNumEntries); for i := 0 to TcpTable.dwNumEntries - 1 do begin with TcpTable.Table[i] do begin FIpTable[i].LocalAddr := Format('%d.%d.%d.%d:%d', [ dwLocalAddr and $FF, (dwLocalAddr shr 8) and $FF, (dwLocalAddr shr 16) and $FF, (dwLocalAddr shr 24) and $FF, ntohs(dwLocalPort) ]); FIpTable[i].RemoteAddr := Format('%d.%d.%d.%d:%d', [ dwRemoteAddr and $FF, (dwRemoteAddr shr 8) and $FF, (dwRemoteAddr shr 16) and $FF, (dwRemoteAddr shr 24) and $FF, ntohs(dwRemotePort) ]); FIpTable[i].pid := dwOwningPid; end; end; end else Begin SetLength(FIpTable,1); FIpTable[0].LocalAddr := 'Error'; FIpTable[0].RemoteAddr := 'Error'; End; finally FreeMem(TcpTable); end; end; function TConnectionListener.GetCount: Integer; begin Result := Length(FIpTable); end; function TConnectionListener.GetItem(Index: Integer): TIpTableItem; begin Result := FIpTable[Index]; end; initialization IpTableLocker := TCriticalSection.Create; finalization IpTableLocker.Free; end. Главное приложение: Код:
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Unit2, Vcl.ExtCtrls, Vcl.StdCtrls; type TForm1 = class(TForm) edConnections: TMemo; edPid: TEdit; lbPid: TLabel; tmConnections: TTimer; procedure tmConnectionsTimer(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } FThread : TConnectionListener; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin FThread := TConnectionListener.Create(True); FThread.FreeOnTerminate := False; FThread.Start; end; procedure TForm1.FormDestroy(Sender: TObject); begin FThread.Terminate; FThread.WaitFor; FThread.Free; end; procedure TForm1.tmConnectionsTimer(Sender: TObject); var I : Integer; iPid : Cardinal; begin tmConnections.Enabled := False; IpTableLocker.Enter; iPid := StrToIntDef(edPid.Text,0); edConnections.Lines.BeginUpdate; Try edConnections.Lines.Clear; for I := 0 to FThread.Count-1 do if (iPid = 0) Or (iPid = FThread.IpTable[i].pid) then edConnections.Lines.Add(Format('%d: %s <=> %s',[FThread.IpTable[i].pid, FThread.IpTable[i].LocalAddr,FThread.IpTable[i].RemoteAddr])); Finally edConnections.Lines.EndUpdate; IpTableLocker.Leave; tmConnections.Enabled := True; End; end; end. |
Этот пользователь сказал Спасибо lmikle за это полезное сообщение: | ||
leon2009 (11.07.2025)
|