Я пишу код сокета C ++, используя Visual Studio Express 2013 в .dll-проекте. Я нахожусь в точке, где я получаю ошибку в этом sendto
функция:
/* Send data back */
if (sendto(sd, (const char *)sendBuffer,(int)sizeof(sendBuffer), 0,
(struct sockaddr *)&client, sizeof(client)) ==
SOCKET_ERROR)
{
err = WSAGetLastError();
closesocket(sd);
WSACleanup();
throw std::runtime_error("Error sending datagram.");}
Я знаю, что мы можем получить код ошибки с WSAGetLastError()
, но если я инициализирую его переменной, я просто получаю ненужные числа. Как извлечь sendto
ошибка? У меня есть модульные тесты, написанные для проверки этой DLL, но я не уверен, есть ли способ, которым я могу просто распечатать ошибку.
Изменить: Таким образом, после изменения условия на == не! = Оно больше не терпит неудачу в sendto
но теперь терпит неудачу в
bytes_received = recvfrom(sd, readBuffer, NTP_PACKET_MAX, 0, (struct sockaddr *)&client, &len);
if (bytes_received == SOCKET_ERROR)
{
err = WSAGetLastError();
closesocket(sd);
WSACleanup();
throw std::runtime_error("Could not receive datagram.");
}
Как и в оригинальном вопросе, я не уверен, как получить правильную ошибку. При отладке recvfrom
функция, я нахожусь над err
и он говорит, что значение, которое он держит, равно 114351196. Из того, что я вижу, это не является действительным кодом ошибки Windows Socket.
Пара плохих ошибок в вашем коде
/* Send data back */
if (sendto(sd, (const char *)sendBuffer,(int)sizeof(sendBuffer), 0,
(struct sockaddr *)&client, sizeof(client)) !=
SOCKET_ERROR) // SHOULD BE == (1)
{
throw std::runtime_error("Error sending datagram.");
// UNREACHABLE CODE (2)
closesocket(sd);
WSACleanup();
}
Ошибка 1: Ваш блок ошибок вводится при успешной отправке. Это может означать, что ваша ошибка не инициализирована (в противном случае это будет последнее значение ошибки из другого места). Согласно документации MSDN для WSAGetLastError
, функция должна быть вызвана немедленно после сбоя в работе WinSocket, и только в этих обстоятельствах.
Если вы позвоните ему после успешной операции (которую вы делаете), тогда нет никакой гарантии, какую ценность вы получите. Если это может быть последняя ошибка другой операции WinSocket в этом потоке, это может быть 0, это может быть какое-то другое значение. В документах не указывается, что происходит, если ошибка извлекается, когда ни одна операция не завершилась, и поэтому вы можете рассматривать это как неопределенное поведение.
Ошибка 2: После того, как вы сгенерируете свое исключение, функция немедленно завершится Ты не будешь звонить closesocket
или же WSACleanup
ОБНОВИТЬ:
Я предполагаю, что вы проверяете значение err
в отладчике, прежде чем назначить ему какое-либо значение. Вы должны делать что-то вроде:
bytes_received = recvfrom(sd, readBuffer, NTP_PACKET_MAX, 0, (struct sockaddr *)&client, &len);
if (bytes_received == SOCKET_ERROR)
{
int err = WSAGetLastError();
// In debugger you must be here before err is set
closesocket(sd);
WSACleanup();
std::string what{"Could not receive datagram."};
what+= std::to_string(err);
throw std::runtime_error(what.c_str());
}
Других решений пока нет …