LINUX.ORG.RU

UDP Socket peek


0

1

Привет. Есть вот такой код:

receivedBytes = recvfrom(socket, NULL, <много>, MSG_PEEK, NULL, NULL);
Используется для того, чтобы узнать размер входящего пакета, а последующий recvfrom уже будет использоваться с буфером нужного размера. Сдаётся мне, что так использовать recvfrom неправильно, поскольку руководство говорит:

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.

Есть ли более правильные способы это реализовать?

★★★★★

Да, передавать NULL в качестве буфера с указанием ненулевого размера - некорректно. Кроме того, posix говорит:

The recvfrom() function shall return the length of the message written to the buffer pointed to by the buffer argument.

Обычно достаточно указывать буфер максимального размера. Если очень хочется работать с буфером произвольного размера, тогда делайте realloc буфера (текущий размер * 2) в случае, когда recvfrom с MSG_PEEK вернул текущий размер буфера.

Sorcerer ★★★★★ ()

FIONREAD есть для линукса, но не помню она для tcp только или для udp тоже а так конечно правильно как уже ответили, заранее обьявлять больший буффер а потом его коммитить или обрезать по аналогиии boost/prepare/commit

anonymous ()
ioctl FIONREAD
              Gets a pointer to an integer as argument.  Returns the size of
              the next pending datagram in the integer in bytes, or 0 when
              no datagram is pending.

Итого

ioctl(socket, FIONREAD, &receivedBytes);

Только перед тем, как его вызывать надо убедиться, что данные пришли.

anonymous ()

The practical limit for the data length which is imposed by the underlying IPv4 protocol is 65,507 bytes (65,535 − 8 byte UDP header − 20 byte IP header)

Т.е. можно брать буфер в 64К, больше все равно не прилетит. Или у тебя мало памяти?

anonymous ()
Ответ на: комментарий от anonymous

Т.е. можно брать буфер в 64К, больше все равно не прилетит. Или у тебя мало памяти?

Мало. Иначе бы не заморачивался с определением длины.

UVV ★★★★★ ()
Ответ на: комментарий от anonymous

FIONREAD и в винде есть.

Только там ioctlsocket, а так всё то же самое.

anonymous ()
Ответ на: комментарий от anonymous

Ок, понял, спасибо. Оригинальный код, кстати, тоже работает, но, я так понимаю, что вариант с ioctl более правильный и меньше вероятности поймать ай-ай-ай там, где не ждёшь.

UVV ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.