【问题标题】:What can cause ERROR_CONNECTION_ABORTED when calling GetQueuedCompletionStatus调用 GetQueuedCompletionStatus 时可能导致 ERROR_CONNECTION_ABORTED 的原因
【发布时间】:2020-02-25 17:01:27
【问题描述】:

我继承了一些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;
}

服务器连接到客户端,并且两者之间的一些消息被正确处理。但是,有几条消息会导致此错误,我不知道为什么。

这个错误的原因是什么,如何调试?

【问题讨论】:

  • 起初你不检查bResult - 如果它是真的 - GetLastError() 在这里没有意义。如果bResult 为假-这是实际错误,但GetQueuedCompletionStatus 与此无关-您只需获得某些I/O 操作的最终状态。什么操作 - 你不显示,根据你的信息不可能说一些具体的东西
  • 我已编辑问题以提供更多上下文
  • 这是真正的代码?!例如,当bResult 为真时,您如何处理案例?反正只是通过一些代码sn-p不可能在这里发现问题
  • 我现在已经包含了 while 函数

标签: c++ windows sockets tcp


【解决方案1】:

这个问题实际上与 tcp 通信无关。 应用程序抛出了一个深埋的未处理异常,导致了奇怪的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    相关资源
    最近更新 更多