I have a problem – I don’t know the amount of data being sent to my UDP server.
The current code is this – testing in 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 could set recvfrom to 65535 or some other large number but this seems like an unnecessary hack.
recvfrom and recvfrom_nonblock both throw away anything after that length specified.
Am I setting the socket up incorrectly?
Note that UDP is a datagram protocol, not a stream like TCP. Each read from UDP socket dequeues one full datagram. You might pass these flags to
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.If you really don’t know how large of a packet you might get (protocol limit is
65507bytes, see here) and don’t care about doubling the number of system calls, do theMSG_PEEKfirst, then read exact number of bytes from the socket.Or you can set an approximate max buffer size, say
4096, then useMSG_TRUNCto check if you lost any data.Also note that UDP datagrams are rarely larger then
1472– ethernet data size of1500minus20bytes of IPv4 header minus8bytes of UDP header – nobody likes fragmentation.Edit:
Socket::MSG_PEEKis there, for others you can use integer values:Look into your system headers (
/usr/include/bits/socket.hon Linux) to be sure.