Обратите внимание, что UDP - это протокол дейтаграммы , а не поток , как TCP.При каждом чтении из сокета UDP происходит одна полная датаграмма .Вы можете передать эти флаги recvfrom(2)
:
MSG_PEEK
This flag causes the receive operation to return
data from the beginning of the receive queue without
removing that data from the queue. Thus, a subsequent
receive call will return the same data.
MSG_WAITALL
This flag requests that the operation block until the
full request is satisfied. However, the call may still
return less data than requested if a signal is caught,
an error or disconnect occurs, or the next data to be
received is of a different type than that returned.
MSG_TRUNC
Return the real length of the packet, even when it was
longer than the passed buffer. Only valid for packet sockets.
Если вы действительно не знаете, какой размер пакета вы можете получить (ограничение протокола составляет 65507
байт, см. здесь ) и вам не нужно удваивать количество системных вызовов, сначала выполните MSG_PEEK
, а затем прочитайте точное количество байтов из сокета.
Или вы можете установить приблизительное числомаксимальный размер буфера, скажем 4096
, затем используйте MSG_TRUNC
, чтобы проверить, не потеряли ли вы какие-либо данные.
Также обратите внимание, что дейтаграммы UDP редко превышают 1472
- размер данных Ethernet 1500
минус 20
байтов заголовка IPv4 минус 8
байтов заголовка UDP - никому не нравится фрагментация.
Редактировать:
Socket::MSG_PEEK
есть, для других вы можете использовать целочисленные значения:
MSG_TRUNC 0x20
MSG_WAITALL 0x100
Проверьте заголовки вашей системы (/usr/include/bits/socket.h
в Linux), чтобы убедиться.