Visual C++ 2017网络编程实战
上QQ阅读APP看书,第一时间看更新

2.7 获取本机上的TCP统计数据

前面有例子获取了本机的IP协议统计数据,现在我们来获取TCP协议的统计数据。该功能可以通过函数GetTcpStatistics实现,该函数声明如下:

    ULONG GetTcpStatistics(  PMIB_TCPSTATS pStats);

其中,参数pStats指向MIB_TCPSTATS结构的指针,该结构接收本地计算机的TCP统计信息。如果函数成功,返回值为NO_ERROR;如果函数失败,返回值是以下错误代码:

·ERROR_INVALID_PARAMETER:pStats参数为空,或者GetTcpStatistics无法写入pStats参数指向的内存。

结构体MIB_TCPSTATS定义如下:

    typedef struct _MIB_TCPSTATS
    {
        DWORD       dwRtoAlgorithm;            //正在使用的重传超时(RTO)算法
        DWORD       dwRtoMin;                  // 以毫秒为单位的最小RTO值
        DWORD       dwRtoMax;                  // 以毫秒为单位的最大RTO值
        DWORD   dwMaxConn;// 最大连接数。若此成员为-1,则最大连接数是可变的
        //活动打开的次数。在活动打开状态下,客户端正在启动与服务器的连接
        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;

【例2.7】获取本机TCP协议的统计数据

(1)新建一个对话框工程Demo。

(2)切换到资源视图,在对话框上放一个列表框和一个按钮。其中,列表框的ID是IDC_LIST。双击按钮,为其添加事件响应代码:

    void CDemoDlg::OnTest()
    {
    CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST);
    pListBox->ResetContent();

    MIB_TCPSTATS TCPStats;

    //获得TCP协议统计信息
    if (GetTcpStatistics(&TCPStats) != NO_ERROR)
    {
         return;
    }

    CString strText = _T("");
    strText.Format(_T("time-out algorithm:%d"),
         TCPStats.dwRtoAlgorithm);
    pListBox->AddString(strText);
    strText.Format(_T("minimum time-out:%d"),
         TCPStats.dwRtoMin);
    pListBox->AddString(strText);
    strText.Format(_T("maximum time-out:%d"),
         TCPStats.dwRtoMax);
    pListBox->AddString(strText);
    strText.Format(_T("maximum connections:%d"),
         TCPStats.dwMaxConn);
    pListBox->AddString(strText);
    strText.Format(_T("active opens:%d"),
         TCPStats.dwActiveOpens);
    pListBox->AddString(strText);
    strText.Format(_T("passive opens:%d"),
         TCPStats.dwPassiveOpens);
    pListBox->AddString(strText);
    strText.Format(_T("failed attempts:%d"),
         TCPStats.dwAttemptFails);
    pListBox->AddString(strText);
    strText.Format(_T("established connections reset:%d"),
         TCPStats.dwEstabResets);
    pListBox->AddString(strText);
    strText.Format(_T("established connections:%d"),
         TCPStats.dwCurrEstab);
    pListBox->AddString(strText);
    strText.Format(_T("segments received:%d"),
         TCPStats.dwInSegs);
    pListBox->AddString(strText);
    strText.Format(_T("segment sent:%d"),
         TCPStats.dwOutSegs);
    pListBox->AddString(strText);
    strText.Format(_T("segments retransmitted:%d"),
         TCPStats.dwRetransSegs);
    pListBox->AddString(strText);
    strText.Format(_T("incoming errors:%d"),
         TCPStats.dwInErrs);
    pListBox->AddString(strText);
    strText.Format(_T("outgoing resets:%d"),
         TCPStats.dwOutRsts);
    pListBox->AddString(strText);
    strText.Format(_T("cumulative connections:%d"),
         TCPStats.dwNumConns);
    pListBox->AddString(strText);
    }

在DemoDlg.cpp开头包含头文件和引用库文件:

    #include <Iphlpapi.h>                //包含头文件
    #pragma comment(lib,"IPHlpApi.lib")  //引用库文件

(3)保存工程并运行,运行结果如图2-11所示。

图2-11