[BlueLeaf1336]> PROBLEMS> WinSock>

WinSock - TCP状態の一覧取得

historyTOP

2004/05/03:作成

referenceTOP

commentTOP

バイトキャストするところが怪しいですよね。かなり。そのあたりがオリジナルのC++とはかなり感じが違うので、ついでに出力をちょっとヨイカンジにしています。

いいいいい、WinSockじゃないヨ。

code(iphlpapi.pas)TOP

unit IPHLPAPI;

interface

uses
    Windows;

const
    IPHLPAPI_DLL = 'IPHLPAPI.DLL';

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;

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;

implementation

function GetTcpTable; stdcall; external IPHLPAPI_DLL;

end.

code(Main.pas)TOP

uses
    iphlpapi;

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'
    );

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;
    //  第1パラメータにNULLをおいて、必要サイズを取得
    GetTcpTable(nil, d, 0);

    //  MIB_TCPTABLEへのポインタに、必要サイズを確保する
    TcpTable := SysGetMem(d);

    if Assigned(TcpTable) then
    begin

        try
            //  TCPテーブルの取得
            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('+---+-----+---------------------+---------------------+-----------+');

                //  取得したテーブル数は、dwNumEntriesで分かる
                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;
                    //  LISTEN 状態のリモート側のポート番号は無効な値が入っているようです
                    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
            //  MIB_TCPTABLEへのポインタに、確保したメモリを解放する
            SysFreeMem(TcpTable);
        end;
    end;
end;

screenshot & downloadTOP

ソースダウンロード
20040503GetTcpTable.zip(168,555bytes)

EOFTOP