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 равно нулю.

Таким образом, вы не можете получить часть входящего сообщения, получение возвращается только тогда, когда ОС может обработать и вернуть поставленную в очередь дейтаграмму.

Другие вопросы по тегам