SetPerTcpConnectionEStats терпит неудачу и не может получить GetPerTcpConnectionEStats несколько раз c ++ - PullRequest
0 голосов
/ 12 октября 2019

Я следую примеру в https://docs.microsoft.com/en-gb/windows/win32/api/iphlpapi/nf-iphlpapi-getpertcp6connectionestats?redirectedfrom=MSDN, чтобы получить статистику TCP. Хотя я все заработал и в первую очередь получаю статистику, я все же хочу записывать их каждые интервалы времени (что мне не удалось сделать), и у меня есть следующие вопросы.

  1. SetPerTcpConnectionEStats () завершается с ошибкой со статусом! = NO_ERROR и равняется 5. Хотя это не удается, я могу получить статистику. Почему?
  2. Я хочу получать статистику каждые, скажем, 1 секунду. Я пробовал два разных способа;а) чтобы использовать цикл while и использовать std :: this_thread :: sleep_for (1s), где я мог получать статистику каждые ~ 1сек, но все приложение зависало (это из-за этого), я предположил, что яя блокирую работу основного и 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));
  }
}

б)

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();
}

1 Ответ

0 голосов
/ 12 октября 2019

Я нашел решение для второй части моего вопроса. Я размещаю это здесь, в случае, если кто-то найдет это полезным. Могут быть и другие решения, более продвинутые, но я сам так сделал. Мы должны сначала получить MIB_TCPROW, соответствующий TCP-соединению, а затем включить сбор 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...