TCP の統計情報を取得する

ここでは TCP の統計情報を取得します。

コマンドなら netstat を使って取得できるような統計情報になります。 次のようなオプションで取得したような情報になります。

> netstat -esa -p tcp

このような情報は IP Helper Function という関数群に実装されています。 TCP の統計情報は GetTcpStatisticsEx 関数で取得可能です。

関数のプロトタイプは次の通りです。

DWORD GetTcpStatisticsEx(
  __out  PMIB_TCPSTATS pStats,
  __in   DWORD dwFamily
);

ここで登場する MIB_TCPSTATS は次の通りです。

typedef struct _MIB_TCPSTATS {
  DWORD dwRtoAlgorithm;
  DWORD dwRtoMin;
  DWORD dwRtoMax;
  DWORD dwMaxConn;
  DWORD dwActiveOpens;
  DWORD dwPassiveOpens;
  DWORD dwAttemptFails;
  DWORD dwEstabResets;
  DWORD dwCurrEstab;
  DWORD dwInSegs;
  DWORD dwOutSegs;
  DWORD dwRetransSegs;
  DWORD dwInErrs;
  DWORD dwOutRsts;
  DWORD dwNumConns;
} MIB_TCPSTATS, *PMIB_TCPSTATS;

ちなみに typedef で *P... という定義を用いる方法は、先日 Windows プログラミングメルマガでも紹介したとおりです。

また、MIB_TCPSTATS 構造体のフィールドのそれぞれの意味についは、下記のコードを確認してみてください。

#include <winsock2.h>
#include <stdio.h>
#include <iphlpapi.h>


void PrintTCPStats(PMIB_TCPSTATS pTcpStat) {

     char *lpAlg;

     switch(pTcpStat->dwRtoAlgorithm) {
     case MIB_TCP_RTO_CONSTANT: lpAlg = "Constant Time-out"; break; 
     case MIB_TCP_RTO_RSRE:     lpAlg = "MIL-STD-1778"; break; 
     case MIB_TCP_RTO_VANJ:     lpAlg = "Van Jacobson's Algorithm"; break; 
     case MIB_TCP_RTO_OTHER:    lpAlg = "Other"; break;
     }

     printf("Retransmission time-out (RTO) Algorithm: %s\n", lpAlg);
     printf("Min. Transmission time-out: %d\n", pTcpStat->dwRtoMin);
     printf("Max. Transmission time-out: %d\n", pTcpStat->dwRtoMax);
     printf("Max. Number of Connections: ");

     if(-1 == pTcpStat->dwMaxConn) {
          printf("Variable\n");
     }
     else {
          printf("%d\n", pTcpStat->dwMaxConn);
     }
     printf("Active Open: %d\n", pTcpStat->dwActiveOpens);
     printf("Passive Open: %d\n", pTcpStat->dwPassiveOpens);
     
     printf("Failed Attempts: %d\n", pTcpStat->dwAttemptFails);
     printf("Reset: %d\n", pTcpStat->dwEstabResets);
     printf("Current Established: %d\n", pTcpStat->dwEstabResets);
     printf("Segments Received: %d\n", pTcpStat->dwInSegs);
     printf("Segments Sent: %d\n", pTcpStat->dwOutSegs);
     printf("Segments Retransmitted: %d\n", pTcpStat->dwRetransSegs);
     printf("Imcoming Errors: %d\n", pTcpStat->dwInErrs);
     printf("Outgoing Resets: %d\n", pTcpStat->dwOutRsts);
     printf("Cumulative Connections: %d\n", pTcpStat->dwNumConns);

}


void main() {

     DWORD dwRet;
     MIB_TCPSTATS tcpstat;
     
     dwRet = GetTcpStatisticsEx(&tcpstat, AF_INET);

     if(dwRet != NO_ERROR) {
          printf("GetTcpStatisticsEx Failed (%d)\n", GetLastError());
          return;
     }

     PrintTCPStats(&tcpstat);

}

上記のコードを tcpstat.cpp として保存します。

コンパイルする時は、iphlpapi.lib とリンクさせます。次のコマンドで tcpstat.exe が出来上がります。

> cl iphlpapi.lib  tcpstat.cpp
> tcpstat.exe
Retransmission time-out (RTO) Algorithm: MIL-STD-1778
Min. Transmission time-out: 10
Max. Transmission time-out: -1
Max. Number of Connections: Variable
Active Open: 51039
Passive Open: 2014
Failed Attempts: 22426
Reset: 15226
Current Established: 15226
Segments Received: 2305607
Segments Sent: 1322787
Segments Retransmitted: 57524
Imcoming Errors: 2
Outgoing Resets: 29408
Cumulative Connections: 53

>

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Web/DB プログラミング徹底解説