Я унаследовал некоторый код сервера 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;
}
Сервер подключается к клиенту, и некоторые сообщения между ними обрабатываются правильно. Однако есть несколько сообщений, которые вызывают эту ошибку, и я понятия не имею, почему.
Каковы причины этой ошибки и как их можно отладить?