Что может вызвать ошибку ERROR_CONNECTION_ABORTED при вызове GetQueuedCompletionStatus - PullRequest
0 голосов
/ 30 октября 2019

Я унаследовал некоторый код сервера Windows TCP, но обнаружил, что он не работает.

Я звоню GetQueuedCompletionStatus(), и это генерирует ошибку ERROR_CONNECTION_ABORTED.

Код, который вызывает его:

unsigned int WinTCPServer::runWorker()
{
   unsigned int returnValue = 0U;

   bool bStayAlive = true;
   while (bStayAlive)
   {
      // Wait for IOCP events.
      DWORD bytesTransferred = 0U;
      ULONG_PTR completionKey = 0U;
      LPOVERLAPPED pOverlapped = NULL;
      BOOL bResult = GetQueuedCompletionStatus(_hIOCP, &bytesTransferred, &completionKey, &pOverlapped, INFINITE);

      if (FALSE == bResult)
      {
         // If pOverlapped == NULL then no packet was dequeued, the other parameters contain
         // undefined values, and we can't tell which socket it was. If pOverlapped != NULL,
         // the function has dequeued a failed completion packet.
         if (pOverlapped == NULL)
         {
            std::string error = "GetQueuedCompletionStatus failed, unknown context, interface id: " + std::to_string(_interfaceID);
            _consoleLog.AppError(__FILE__, __LINE__, error);
         }
         else
         {
            // If the completion key is zero, this was a shut-down post that failed
            // (PostQueuedCompletionStatus with zero). This shouldn't happen! No real
            // way of handling this gracefully.
            if (0U == completionKey)
            {
               _consoleLog.PlatformError(__FILE__, __LINE__, "GetQueuedCompletionStatus failed", GetLastError());
               std::string error = "TCP server shut down error, interface ID " + std::to_string(_interfaceID);
               _consoleLog.AppError(__FILE__, __LINE__, error);
            }
            else
            {
               // Don't report client disconnections as errors.
               DWORD lastError = GetLastError();
               if ((ERROR_NETNAME_DELETED != lastError) && (ERROR_OPERATION_ABORTED != lastError))
               {
                  _consoleLog.PlatformError(__FILE__, __LINE__, "GetQueuedCompletionStatus failed", lastError);
               }

               // Perform any outstanding actions on the overlapped operation.
               WinTCPClientContext* pClientContext = reinterpret_cast<WinTCPClientContext*>(completionKey);
               pClientContext->ProcessIncompleteOverlapped(pOverlapped);

               // We don't want to use this client any more.
               removeClient(*pClientContext);
            }
         }
      }
      else
      {
         // A null client context means the server is shutting down (i.e. has called
         // PostQueuedCompletionStatus with a NULL value).
         if (0U == completionKey)
         {
            bStayAlive = false;
         }
         else
         {
            // Convert the completion key into the client context.
            WinTCPClientContext* pClientContext = reinterpret_cast<WinTCPClientContext*>(completionKey);
            if (0U == bytesTransferred)
            {
               // This means a gracefull disconnection of the client. 
               // We should get this for every outstanding post (i.e. 
               // outstanding reads and writes).
               pClientContext->ProcessIncompleteOverlapped(pOverlapped);

               // We don't want to use this client any more.
               removeClient(*pClientContext);
            }
            else
            {
               // Process the overlapped result
               try
               {
                  // Process the post.
                  pClientContext->ProcessOverlapped(pOverlapped, bytesTransferred);
               }
               catch (utility::CommsException& ex)
               {
                  _consoleLog.PlatformError(ex.Filename(), ex.Line(), ex.Error(), ex.ErrorCode());
                  _consoleLog.StatusInfo(__FILE__, __LINE__, "client error, disconnecting");

                  // We don't want to use this client any more.
                  removeClient(*pClientContext);
               }
               catch (utility::Exception& ex)
               {
                  _consoleLog.AppError(ex.Filename(), ex.Line(), ex.Error());
                  _consoleLog.StatusInfo(__FILE__, __LINE__, "client error, disconnecting");

                  // We don't want to use this client any more.
                  removeClient(*pClientContext);
               }
            }
         }
      }
   }

   return returnValue;
}

Сервер подключается к клиенту, и некоторые сообщения между ними обрабатываются правильно. Однако есть несколько сообщений, которые вызывают эту ошибку, и я понятия не имею, почему.

Каковы причины этой ошибки и как их можно отладить?

1 Ответ

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

Эта проблема на самом деле не имела ничего общего с tcp comms. Приложение выдавало глубоко скрытое необработанное исключение, вызывающее странное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...