Получение недокументированного кода ошибки из recvfrom - PullRequest
0 голосов
/ 06 июня 2019

При попытке чтения пакетов UDP с использованием recvfrom функция возвращает -1, указывая на ошибку. Я, конечно, тогда звоню WSAGetLastError, чтобы узнать, в чем проблема. Сообщенный номер ошибки - 183. Я не могу найти какую-либо ссылку на то, что означает это число.

Edit:

while (bytesRecv != SOCKET_ERROR)
    {
        //  get data from the server
        bytesRecv = recvfrom(m_socket, (char*)&receiveData, sizeof(ReceiveData), 0, (struct sockaddr *) &server_addr, &server_addr_len);
        logError("Bytes recieved: ", bytesRecv);
        // if data was recieved from the server
        if (bytesRecv > 0)
        {
            //Data packet processing code
        }
        else
        {
            if (bytesRecv == SOCKET_ERROR)
            {
                logError("Error: Reading data: ", WSAGetLastError());
            }
        }
    }

Edit:

void logError(const std::string &text, int errorCode)
{
    std::ofstream log_file("error_log_file.txt", std::ios_base::out | std::ios_base::app);

    log_file << text << errorCode << "\n";
}

1 Ответ

2 голосов
/ 06 июня 2019

Проблема не в самом WSAGetLastError().Реальная проблема заключается в том, что вы звоните logError() перед вызовом WSAGetLastError(), а logError() в итоге сбрасывает код последней ошибки на 183.

logError() использует std::ofstream, чтобы открыть файл дляДобавление данных.В Windows эта операция в конечном итоге вызовет CreateFile() с флагом OPEN_ALWAYS, для которого в документации указано:

Всегда открывает файл.

Если указанный файл существует, функция завершается успешно , а код последней ошибки устанавливается в ERROR_ALREADY_EXISTS (183) .

Если указанный файл не существует и является допустимым путем кдоступное для записи место, функция создает файл , а код последней ошибки устанавливается равным нулю .

...

Если функция завершается ошибкой, возвращаемое значение равно INVALID_HANDLE_VALUE,Чтобы получить расширенную информацию об ошибках, вызовите GetLastError .

Внутренне, WSAGetLastError() просто отображается на GetLastError() (хорошо известная, но недокументированная деталь реализации).Таким образом, независимо от того, удастся ли CreateFile() открыть файл или нет, код ошибки, сообщенный WSAGetLastError(), будет сброшен до результата операции открытия.

Ваш вызов logError() находится внеправильное местоЕго нужно переместить внутрь вашего блока if (bytesRecv > 0) (кстати, UDP поддерживает дейтаграммы 0 длины, поэтому вы должны использовать >= вместо >):

while (true)
{
    //  get data from the server
    bytesRecv = recvfrom(m_socket, (char*)&receiveData, sizeof(ReceiveData), 0, (struct sockaddr *) &server_addr, &server_addr_len);
    // if data was received from the server
    if (bytesRecv >= 0)
    {
        logError("Bytes received: ", bytesRecv); // <-- moved here!!!
        //Data packet processing code
    }
    else // if (bytesRecv == SOCKET_ERROR)
    {
        logError("Error: Reading data: ", WSAGetLastError());
        break;
    }
}

В качестве альтернативы:

while (true)
{
    //  get data from the server
    bytesRecv = recvfrom(m_socket, (char*)&receiveData, sizeof(ReceiveData), 0, (struct sockaddr *) &server_addr, &server_addr_len);
    // if data was received from the server
    if (bytesRecv == SOCKET_ERROR)
    {
        logError("Error: Reading data: ", WSAGetLastError());
        break;
    }

    logError("Bytes received: ", bytesRecv); // <-- moved here!!!
    //Data packet processing code
}
...