【问题标题】:SetPerTcpConnectionEStats fails and can't get GetPerTcpConnectionEStats multiple times c++SetPerTcpConnectionEStats 失败,无法多次获取 GetPerTcpConnectionEStats c++
【发布时间】:2020-02-09 18:35:12
【问题描述】:

我正在按照https://docs.microsoft.com/en-gb/windows/win32/api/iphlpapi/nf-iphlpapi-getpertcp6connectionestats?redirectedfrom=MSDN 中的示例获取 TCP 统计信息。虽然,我首先得到了它的工作并获得了统计数据,但我仍然想每隔一个时间间隔记录它们(我还没有设法这样做),我有以下问题。

  1. SetPerTcpConnectionEStats () 失败,状态为 != NO_ERROR 并且等于 5。虽然失败,但我可以获得统计信息。为什么?
  2. 我想每隔 1 秒获取一次统计信息。我尝试了两种不同的方法; a) 使用 while 循环并使用 std::this_thread::sleep_for(1s),我可以每隔约 1 秒获得一次统计信息,但整个应用程序正在停止(是因为这个),我想我我阻止了 main 的操作,并且 b)(因为 a) 失败)我试图从另一个函数(在不同的类中)调用 TcpStatistics(),该函数每 1 秒触发一次(我将 clientConnectRow 存储到一个全局变量)。但是,在这种情况下 (b),GetPerTcpConnectionEStats() 失败并显示 winStatus = 1214 (ERROR_INVALID_NETNAME),当然 TcpStatistics() 无法获得任何统计信息。

一)

ClassB::ClassB()
{
   UINT winStatus = GetTcpRow(localPort, hostPort, MIB_TCP_STATE_ESTAB, (PMIB_TCPROW)clientConnectRow);  
   ToggleAllEstats(clientConnectRow, TRUE);
   thread t1(&ClassB::TcpStatistics, this, clientConnectRow); 
   t1.join();
}

ClassB::TcpStatistics()
{
   while (true)
  {
     GetAndOutputEstats(row, TcpConnectionEstatsBandwidth)
     // some more code here
     this_thread::sleep_for(milliseconds(1000));
  }
}

b)

ClassB::ClassB()
{
    MIB_TCPROW client4ConnectRow;
    void* clientConnectRow = NULL;
    clientConnectRow = &client4ConnectRow;
    UINT winStatus = GetTcpRow(localPort, hostPort, MIB_TCP_STATE_ESTAB, (PMIB_TCPROW)clientConnectRow);    
    m_clientConnectRow = clientConnectRow;
    TcpStatistics();
}

ClassB::TcpStatistics()
{
  ToggleAllEstats(m_clientConnectRow , TRUE);
  void* row = m_clientConnectRow;
  GetAndOutputEstats(row, TcpConnectionEstatsBandwidth)
  // some more code here
}

ClassB::GetAndOutputEstats(void* row, TCP_ESTATS_TYPE type)
{
   //...
    winStatus = GetPerTcpConnectionEStats((PMIB_TCPROW)row, type, NULL, 0, 0, ros, 0, rosSize, rod, 0, rodSize);

    if (winStatus != NO_ERROR) {wprintf(L"\nGetPerTcpConnectionEStats %s failed. status = %d",  estatsTypeNames[type], winStatus); // 
    }
    else { ...}
}

ClassA::FunA()
{
  classB_ptr->TcpStatistics();
}

【问题讨论】:

    标签: c++ windows sockets tcp


    【解决方案1】:

    我为我的问题的第二部分找到了解决方法。我把它贴在这里,以防其他人觉得它有用。可能还有其他更高级的解决方案,但这是我自己做的。我们必须首先获取与 TCP 连接对应的 MIB_TCPROW,然后在转储当前统计信息之前启用 Estats 收集。所以,我所做的是将所有这些添加到一个函数中,并在每次我想获取统计信息时调用它。

    void
    ClassB::FunSetTcpStats()
    {
        MIB_TCPROW client4ConnectRow;
        void* clientConnectRow = NULL;
        clientConnectRow = &client4ConnectRow;
    
        //this is for the statistics
        UINT winStatus = GetTcpRow(lPort, hPort, MIB_TCP_STATE_ESTAB, (PMIB_TCPROW)clientConnectRow); //lPort & hPort in htons!
        if (winStatus != ERROR_SUCCESS) {
            wprintf(L"\nGetTcpRow failed on the client established connection with %d", winStatus);
            return;
        }   
        //
        // Enable Estats collection and dump current stats.
        //
        ToggleAllEstats(clientConnectRow, TRUE);
        TcpStatistics(clientConnectRow); // same as GetAllEstats() in msdn
    }
    

    【讨论】:

      猜你喜欢
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-17
      • 2013-01-24
      • 2019-02-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多