본문 바로가기

카테고리 없음

[네트웍/인터넷] IP Helper API 를 이용한 접속 상태 테이블 구하기

반응형
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  const
    MIB_TCP_STATE_CLOSED     =  1;
    MIB_TCP_STATE_LISTEN     =  2;
    MIB_TCP_STATE_SYN_SENT   =  3;
    MIB_TCP_STATE_SYN_RCVD   =  4;
    MIB_TCP_STATE_ESTAB      =  5;
    MIB_TCP_STATE_FIN_WAIT1  =  6;
    MIB_TCP_STATE_FIN_WAIT2  =  7;
    MIB_TCP_STATE_CLOSE_WAIT =  8;
    MIB_TCP_STATE_CLOSING    =  9;
    MIB_TCP_STATE_LAST_ACK   = 10;
    MIB_TCP_STATE_TIME_WAIT  = 11;
    MIB_TCP_STATE_DELETE_TCB = 12;


    MIB_IPADDR_PRIMARY      = $0001;    //  Primary IP address
    MIB_IPADDR_DYNAMIC      = $0004;    //  Dynamic IP address
    MIB_IPADDR_DISCONNECTED = $0008;    //  Address is on disconnected interface
    MIB_IPADDR_DELETED      = $0040;    //  Address is being deleted
    MIB_IPADDR_TRANSIENT    = $0080;    //  Transient address

  type
    MIB_TCPROW = record
      dwState     : DWORD;
      dwLocalAddr : DWORD;
      dwLocalPort : DWORD;
      dwRemoteAddr: DWORD;
      dwRemotePort: DWORD;
    end;
    PMIB_TCPROW = ^MIB_TCPROW;

    MIB_TCPTABLE = record
      dwNumEntries: DWORD;
      table       : array[0..1023] of MIB_TCPROW;
    end;
    PMIB_TCPTABLE = ^MIB_TCPTABLE;

  function GetTcpTable(pTcpTable: Pointer; var pdwSize: LongInt;
                          bOrder: LongInt): LongInt;  stdcall;

  function GetTcpTable; stdcall; external 'IPHLPAPI.DLL';

const
  StateStrings: array[0..12] of string =
  (
      ''           , 'CLOSED'   , 'LISTEN'    , 'SYN_SENT'  , 'SYN_RCVD',
      'ESTABLISHED', 'FIN_WAIT1', 'FIN_WAIT2' , 'CLOSE_WAIT', 'CLOSING' ,
      'LAST_ACK'   , 'TIME_WAIT', 'DELETE_TCB'
  );
  
var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
type
  BCast = array[0..3] of Byte;
var
  d: Integer;
  TcpTable: PMIB_TCPTABLE;
  i: integer;
  Buf: string;
  lip, rip, lpt, rpt, state: Cardinal;
begin
  Memo1.Clear();

  d := 0;
  GetTcpTable(nil, d, 0);

  TcpTable := SysGetMem(d);

  if Assigned(TcpTable) then
  begin
    try
      if GetTcpTable(TcpTable, d, 0) = NO_ERROR then
      begin
        Memo1.Lines.Add('+---+-----+---------------------+---------------------+-----------+');
        Memo1.Lines.Add('|No.|Proto|Local Address        |Foreign Address      |State      |');
        Memo1.Lines.Add('+---+-----+---------------------+---------------------+-----------+');

        for i := 0 to TcpTable.dwNumEntries - 1 do
        begin
          state := (TcpTable.table[i]).dwState;
          lip := (TcpTable.table[i]).dwLocalAddr;
          rip := (TcpTable.table[i]).dwRemoteAddr;
          lpt := (TcpTable.table[i]).dwLocalPort;
          rpt := (TcpTable.table[i]).dwRemotePort;
          if (state = 2) then rpt := 0;

          Buf := Format('|%3.3d|TCP  |%3d.%3d.%3d.%3d:%5d|%3d.%3d.%3d.%3d:%5d|%-11s|',
                      [
                      i,
                      BCast(lip)[0], BCast(lip)[1], BCast(lip)[2], BCast(lip)[3],
                      BCast(lpt)[0] * 256 + BCast(lpt)[1],
                      BCast(rip)[0], BCast(rip)[1], BCast(rip)[2], BCast(rip)[3],
                      BCast(rpt)[0] * 256 + BCast(rpt)[1],
                      StateStrings[state]
                      ]);

          Memo1.Lines.Add(Buf);
        end;

        Memo1.Lines.Add('+---+-----+---------------------+---------------------+-----------+');
      end;
    finally
        SysFreeMem(TcpTable);
    end;
  end;
end;

end.
반응형