Recvfrom: ожидание полного сообщения (сообщение переменного размера, поток)
У меня есть UDP-клиент, который отправляет сообщения на сервер с указанной скоростью. Скорость должна быть постоянной, поэтому я решил попытаться получать ответы в отдельном потоке, чтобы избежать блокировки или задержки recvfrom()
, Можно ли вообще "ждать" полного сообщения перед получением? Какова будет лучшая стратегия для этого?
while (true)
{
//std::this_thread::sleep_for(std::chrono::milliseconds(5000));
if (recvfrom(threadSock, ReceiveBuf, BufLength, 0, 0, 0) == SOCKET_ERROR)
{
printf("Thread Receive failed with error %ld\n", GetLastError());
break;
}
else
{
printf("Reply received: %s\n\n", ReceiveBuf);
}
memset(ReceiveBuf, '\0', BufLength);
}
Выше мой код получения. В настоящее время в буфер считываются только первые 8 символов ответа (размер буфера составляет 512 байт).
Как я могу ждать полного сообщения (имея в виду, что длина сообщения является переменной).
Это вообще возможно? Возможно, есть лучший подход.
Заранее спасибо.
РЕДАКТИРОВАТЬ: я должен уточнить, отпечатки только для тестирования. Они не будут в конечном результате, поскольку печать из потока дает странные встроенные отпечатки.
2 ответа
В интересах полноты и небольшого шанса, что любой, кто страдает от подобной путаницы, обнаружит это, решение следует:
Да, это был глупый вопрос, я должен был понять, что recvfrom ждет полной дейтаграммы. Проблема была с моим сервером.
Это была проблема с сервером, не отправляющим полные данные. Я не уверен относительно точной причины, но чтобы исправить это, я преобразовал char*
мой ответ был сохранен (и правильно распечатан) char[]
, который при отправке работал нормально.
По данным MSDN:
Функция recvfrom получает дейтаграмму и сохраняет адрес источника.
Для сокетов, ориентированных на сообщения, данные извлекаются из первого сообщения в очереди до размера указанного буфера. Если датаграмма или сообщение больше указанного буфера, буфер заполняется первой частью дейтаграммы, и recvfrom генерирует ошибку WSAEMSGSIZE. Для ненадежных протоколов (например, UDP) лишние данные теряются. Для UDP, если полученный пакет не содержит данных (пустых), возвращаемое значение из функции-функции recvfrom равно нулю.
Таким образом, вы не можете получить часть входящего сообщения, получение возвращается только тогда, когда ОС может обработать и вернуть поставленную в очередь дейтаграмму.