Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Интернет и сети
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 04.07.2025, 13:17
leon2009 leon2009 вне форума
Новичок
 
Регистрация: 18.03.2009
Сообщения: 82
Репутация: 10
Стрелка Как по PID вывести соединение программы

Здравствуйте! как зная 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);
у меня ошибка KERNELLBASE
Ответить с цитированием
  #2  
Старый 05.07.2025, 02:02
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

В предыдущем вопросе (https://delphisources.ru/forum/showt...077#post159077) я оставил константу TCP_TABLE_OWNER_PID_ALL при вызове GetExtendedTcpTable. В этом случае в ответе будет также заполнено поле dwOwningPid - там как раз PID процесса, установившего соединение. Соответсвенно, получи PID и просто отфильтруй нужные соединения.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
leon2009 (05.07.2025)
  #3  
Старый 06.07.2025, 21:55
leon2009 leon2009 вне форума
Новичок
 
Регистрация: 18.03.2009
Сообщения: 82
Репутация: 10
Сообщение сортировка

добавил: 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  
Старый 06.07.2025, 22:10
leon2009 leon2009 вне форума
Новичок
 
Регистрация: 18.03.2009
Сообщения: 82
Репутация: 10
Сообщение результат

вот что выдает
Цитата:
PID: 832, Local: 0.0.0.0:135, Remote: 0.0.0.0:0
Ответить с цитированием
  #5  
Старый 07.07.2025, 17:29
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

1. Еще раз - фильтровать лучше на "клиентской" стороне, т.е. там, где ты выводишь.
2. надо посмотреть, может PID тоже надо конвертировать с помощью ntohs
3. Ну и что такого, открыт листенер на 135 порт, но никто туда не подключался еще, хотя конечно 0.0.0.0 смотрится странно.
Ответить с цитированием
  #6  
Старый 07.07.2025, 20:44
leon2009 leon2009 вне форума
Новичок
 
Регистрация: 18.03.2009
Сообщения: 82
Репутация: 10
Печаль

Код:
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
          ]);
и вывод: UNIT1
Код:
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  
Старый 07.07.2025, 20:48
leon2009 leon2009 вне форума
Новичок
 
Регистрация: 18.03.2009
Сообщения: 82
Репутация: 10
Печаль ноль

0.0.0.0 выводил потому что
Код:
TCP_TABLE_BASIC_CONNECTIONS {TCP_TABLE_OWNER_PID_ALL}
делал
Код:
{TCP_TABLE_BASIC_CONNECTIONS} TCP_TABLE_OWNER_PID_ALL
Ответить с цитированием
  #8  
Старый 08.07.2025, 15:10
leon2009 leon2009 вне форума
Новичок
 
Регистрация: 18.03.2009
Сообщения: 82
Репутация: 10
Сообщение 0 в результате

я не могу справиться
ставишь это:
Код:
TCP_TABLE_OWNER_PID_ALL
выводит 0.0.0.0
ставишь
Код:
TCP_TABLE_BASIC_CONNECTIONS
выводит 127.0.0.1
и пустые результаты <=> т.е. соединений много но почему <=> они пустые
Ответить с цитированием
  #9  
Старый 10.07.2025, 03:56
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

пустые - ты if свой убрал?
Код:
// вот этот:
if dwOwningPid = PID then
         begin
 
Там код написан так, что он сразу размечает массив для всех соединений. А если ты ставишь там if, то некоторые ячейки массива оказываются незаполнеными.
Ответить с цитированием
  #10  
Старый 10.07.2025, 19:51
leon2009 leon2009 вне форума
Новичок
 
Регистрация: 18.03.2009
Сообщения: 82
Репутация: 10
Восклицание убрал

да я его убрал: результат будет одинаковый:
Цитата:
127.0.0.1:49684 <=> 127.0.0.1:49693
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
<=>
выдает пустышки. скорее всего
как я понимаю, есть подключение: 1) По локальной сети WAN Miniport = 0.0.0.0 который готов принимать,,,, 2) WANMiniport = 0.0.0.0 и Ethernet Realtec PCIe Family = 192.168.1.0
= Может из за этого выдает пустые результаты ? но хотя ТАБЛИЦА то одна
Ответить с цитированием
  #11  
Старый 11.07.2025, 04:34
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,096
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Не знаю, у меня работает.
Без фильтра:
Цитата:
976: 0.0.0.0:135 <=> 0.0.0.0:0
4: 0.0.0.0:445 <=> 0.0.0.0:0
4524: 0.0.0.0:3050 <=> 0.0.0.0:0
6700: 0.0.0.0:5040 <=> 0.0.0.0:0
4: 0.0.0.0:5357 <=> 0.0.0.0:0
764: 0.0.0.0:49664 <=> 0.0.0.0:0
672: 0.0.0.0:49665 <=> 0.0.0.0:0
1584: 0.0.0.0:49666 <=> 0.0.0.0:0
1332: 0.0.0.0:49667 <=> 0.0.0.0:0
3172: 0.0.0.0:49668 <=> 0.0.0.0:0
744: 0.0.0.0:49677 <=> 0.0.0.0:0
4: 0.0.0.0:50123 <=> 0.0.0.0:0
19264: 127.0.0.1:19293 <=> 0.0.0.0:0
4: 192.168.1.7:139 <=> 0.0.0.0:0
18004: 192.168.1.7:64404 <=> 172.183.7.194:443
18004: 192.168.1.7:64413 <=> 20.169.174.231:443
3764: 192.168.1.7:64421 <=> 172.183.7.194:443
18004: 192.168.1.7:64747 <=> 87.250.251.119:443
18004: 192.168.1.7:64752 <=> 87.250.250.119:443
18004: 192.168.1.7:64824 <=> 172.253.122.17:443
18004: 192.168.1.7:64825 <=> 142.251.163.83:443
0: 192.168.1.7:64826 <=> 142.251.111.95:443
0: 192.168.1.7:64827 <=> 142.250.31.95:443
18004: 192.168.1.7:64828 <=> 142.251.163.83:443
0: 192.168.1.7:64836 <=> 23.207.133.136:80

С фильтром (18004):
Цитата:
18004: 192.168.1.7:64404 <=> 172.183.7.194:443
18004: 192.168.1.7:64413 <=> 20.169.174.231:443
18004: 192.168.1.7:64747 <=> 87.250.251.119:443
18004: 192.168.1.7:64752 <=> 87.250.250.119:443
18004: 192.168.1.7:64824 <=> 172.253.122.17:443
18004: 192.168.1.7:64825 <=> 142.251.163.83:443
18004: 192.168.1.7:64828 <=> 142.251.163.83:443
18004: 192.168.1.7:64845 <=> 13.107.6.158:443

Поток:
Код:
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)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 11:39.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025