Welcome to SapporoWorks! We create stimulating network programs.
By a demand from user, SapporoWorks evolves.
トップページ| ソフトウエア| シェアウエア登録| セキュリティ情報| 開発情報| ドキュメント|
開発情報 > TCP状態の一覧取得(プロセスIDの取得を含むバージョン)


概要

GetTcpTable()を使用すると、現在のTCP状態の一覧が取得できることを、先のTipsでご紹介しましたが、
WindowsXPのnetstatは、 -o オプションで、それぞれのプロセスIDも表示できるようになりました。
今回は、これをプログラムするためのAPI AllocateAndGetTcpExTableFromStack() を紹介します。

ソース
 
 // 型宣言
 typedef struct tagMIB_TCPEXROW{
   DWORD   dwState;        // ステータス
   DWORD   dwLocalAddr;    // ローカル アドレス
   DWORD   dwLocalPort;    // ローカル ポート番号
   DWORD   dwRemoteAddr;   // リモート アドレス
   DWORD   dwRemotePort;   // リモートポート番号
   DWORD   dwProcessId;    // プロセスID
 } MIB_TCPEXROW, *PMIB_TCPEXROW;
 
 typedef struct tagMIB_TCPEXTABLE{
  DWORD   dwNumEntries;
  MIB_TCPEXROW table[ANY_SIZE];
 } MIB_TCPEXTABLE, *PMIB_TCPEXTABLE;
 
 typedef DWORD (WINAPI *PALLOCATE_AND_GET_TCPEXTABLE_FROM_STACK)(
   PMIB_TCPEXTABLE *pTcpTable,
   BOOL bOrder,
   HANDLE heap,
   DWORD zero,
   DWORD flags
 );
 
 static PALLOCATE_AND_GET_TCPEXTABLE_FROM_STACK pAllocateAndGetTcpExTableFromStack=NULL;
 
 char *StateStrings[]={"","CLOSED","LISTEN","SYN_SENT","SYN_RCVD","ESTABLISHED","FIN_WAIT1","FIN_WAIT2",
             "CLOSE_WAIT","CLOSING","LAST_ACK","TIME_WAIT","DELETE_TCB"};
 
 __fastcall TForm1::TForm1(TComponent* Owner)
     : TForm(Owner)
 {
     // iphlpapi.dll からAllocateAndGetTcpExTableFromStackのポインタを取得
     pAllocateAndGetTcpExTableFromStack = (PALLOCATE_AND_GET_TCPEXTABLE_FROM_STACK) GetProcAddress( LoadLibrary( "iphlpapi.dll"),"AllocateAndGetTcpExTableFromStack" );
     if( !pAllocateAndGetTcpExTableFromStack ){
         Memo1->Lines->Add("ERROR can't load AllocateAndGetTcpExTableFromStack ");
     }
 }
 
 void __fastcall TForm1::Button1Click(TObject *Sender)
 {
 
     char Buf[1024];
     in_addr ina;
     unsigned int port;
     unsigned char *p;
 
 
     Memo1->Lines->Clear();
 
     PMIB_TCPEXTABLE TCPExTable;
 
     //TCPテーブルの取得
     if(pAllocateAndGetTcpExTableFromStack(&TCPExTable, TRUE, GetProcessHeap(), 2, 2)){
         Memo1->Lines->Add("ERROR AllocateAndGetTcpExTableFromStack");
         return;
     }
 
     Memo1->Lines->Add("Proto  Local Address\tForeign Address\tState\tProcessID");
 
    //取得したテーブル数は、dwNumEntriesで分かる
     for(unsigned int i=0;idwNumEntries; i++){
         unsigned char *local_ip = (unsigned char * )&(TCPExTable->table[i].dwLocalAddr);
 
         p = (unsigned char * )&(TCPExTable->table[i].dwLocalPort);
         unsigned int local_port = *(p+0)*256 + *(p+1);
 
         unsigned char *remote_ip = (unsigned char * )&(TCPExTable->table[i].dwRemoteAddr);
 
 
         p = (unsigned char * )&(TCPExTable->table[i].dwRemotePort);
         unsigned int remote_port = *(p+0)*256 + *(p+1);
         // LISTEN 状態のリモート側のポート番号は無効な値が入っているようです
         if(*remote_ip==0)
             remote_port=0;
 
         wsprintf(Buf,"TCP  %d.%d.%d.%d:%d\t%d.%d.%d.%d:%d\t%s\t%d"
             ,*(local_ip+0),*(local_ip+1),*(local_ip+2),*(local_ip+3)
             ,local_port
             ,*(remote_ip+0),*(remote_ip+1),*(remote_ip+2),*(remote_ip+3)
             ,remote_port
             ,StateStrings[TCPExTable->table[i].dwState]
             ,TCPExTable->table[i].dwProcessId);
         Memo1->Lines->Add(Buf);
     }
 
 }
 



サンプル

サンプルプログラム実行画面


ソースファイルのダウンロード 010-src.LZH 6Kbyte 実行ファイルのダウンロード 010-bin.LZH 201Kbyte


開発者のための実装系Webマガジンへの投稿
TCP/IPを利用しているプロセス情報を視覚的に表示する
各種のOSで利用可能なAPIとAPIが存在しない場合(WindowsNT/2000)のカーネルオブジェクト参照による情報取得方法を解説。
開発情報 > TCP状態の一覧取得(プロセスIDの取得を含むバージョン)

copyright(c) 1995- SapporoWorks
当サイトはリンクフリーです。リンク時に連絡などは必要有りません。また、どのページにリンクして頂いても構いません。