Чтение буферизованного сокета - PullRequest
1 голос
/ 15 июля 2010

У меня проблема - я не знаю объем данных, отправляемых на мой UDP-сервер.

Текущий код такой - тестирование в irb:

require 'sockets'
sock = UDPSocket.new
sock.bind('0.0.0.0',41588)

sock.read # Returns nothing
sock.recvfrom(1024) # Requires length of data to be read - I don't know this

Iможет установить для recvfrom значение 65535 или другое большое число, но это кажется ненужным хаком.

recvfrom и recvfrom_nonblock оба выбрасывают что-либо после указанной длины.

Я неправильно настраиваю сокет?

Ответы [ 2 ]

4 голосов
/ 15 июля 2010

Обратите внимание, что 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), чтобы убедиться.

2 голосов
/ 15 июля 2010

Глядя на документацию для recvfrom () Руби, аргумент имеет длину максимум . Просто укажите 65535 (максимальная длина дейтаграммы UDP); возвращаемые данные должны быть отправленной датаграммой любого размера, и вы должны быть в состоянии определить их размер так же, как для любой строковой вещи в Ruby.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...