Как диагностировать «случайные» сбои winsock - PullRequest
0 голосов
/ 18 октября 2019

У меня есть приложение winsock2, работающее под Windows на обоих концах. MSVC ++ 2017 - это моя среда разработки. Не вдаваясь в подробности, оба конца (оба написаны мной) отправляют небольшие сообщения туда и обратно. Оба конца работают как служба Windows, а соединение должно работать часами или днями. Проблема в том, что на одном его конце (назовите его машиной A), после нормальной работы в течение часа или более, кажется, что соединение разрывается. Машина A отправляет сообщение на машину B, которое получено, затем машина B отправляет ответ обратно. Машина A имеет сокет в неблокирующем режиме, поэтому она входит в цикл вызова recv (), пока не появятся данные. Если он получает WSAEWOULDBLOCK, он проверяет, произошел ли интервал ожидания, если нет, возвращается к Recv (). Ошибка возникает из-за истечения времени ожидания (3 минуты). Нет никакой возможности задержать данные так долго, что-то скрыто. Последующее выполнение send () с компьютера A приводит к ошибке 10054, сброс соединения.

Как я уже сказал, это может работать без проблем в течение нескольких часов. В других случаях я видел, как это провалилось через 45 минут или около того. Обе машины настроены так, чтобы не переходить в режим энергосбережения или что-либо подобное. Может кто-нибудь подсказать, как мне решить эту проблему?

Обновление: пример кода. Цель состоит в том, чтобы подождать, пока не будет получен буфер определенной длины (tlen), и позволить процедуре истечь время ожидания, если что-то пошло не так:

while (TRUE) {
   Sleep(1);
   iret = recv(isocket, s, rlen, 0);
   err = WSAGetLastError();
   if (iret == SOCKET_ERROR) {
      if (err == WSAEWOULDBLOCK) {
        time(&tcur);
        if (tcur > tend) {
          com_Log("Timeout on recv 1");
          return(FALSE);
        }
        continue;
      }
      com_Log("Error on recv, error=%lu", err);
      return(FALSE);
   }

   time(&tend);
   tend = tend + gTimeOut;
   clen = clen + iret;
   if (clen >= tlen) break;
   s = s + iret;
   rlen = rlen - iret;

}
...