recvfrom_nonblock
recvfrom_nonblock(*args)
public
Receives up to maxlen bytes from udpsocket using recvfrom(2) after O_NONBLOCK is set for the underlying file descriptor. If maxlen is omitted, its default value is 65536. flags is zero or more of the MSG_ options. The first element of the results, mesg, is the data received. The second element, sender_inet_addr, is an array to represent the sender address.
When recvfrom(2) returns 0, Socket#recvfrom_nonblock returns an empty string as data. It means an empty packet.
Parameters
-
maxlen - the number of bytes to receive from the socket
-
flags - zero or more of the MSG_ options
Example
require 'socket' s1 = UDPSocket.new s1.bind("127.0.0.1", 0) s2 = UDPSocket.new s2.bind("127.0.0.1", 0) s2.connect(*s1.addr.values_at(3,1)) s1.connect(*s2.addr.values_at(3,1)) s1.send "aaa", 0 begin # emulate blocking recvfrom p s2.recvfrom_nonblock(10) #=> ["aaa", ["AF_INET", 33302, "localhost.localdomain", "127.0.0.1"]] rescue IO::WaitReadable IO.select([s2]) retry end
Refer to Socket#recvfrom for the exceptions that may be thrown if the call to recvfrom_nonblock fails.
UDPSocket#recvfrom_nonblock may raise any error corresponding to recvfrom(2) failure, including Errno::EWOULDBLOCK.
If the exception is Errno::EWOULDBLOCK or Errno::AGAIN, it is extended by IO::WaitReadable. So IO::WaitReadable can be used to rescue the exceptions for retrying recvfrom_nonblock.
See
Receiving data over UDP
It’s perfectly normal to receive ‘X’ strings with Ruby’s UDP sockets before the actual content.
Consider the following example:
require 'socket' PORT = 5500 socket = UDPSocket.new socket.bind('', PORT) for i in 1..10 IO.select([socket]) p socket.recvfrom_nonblock(4096) end
Now, sending data with netcat:
echo "Hello APIdock" | nc -vv -u 127.0.0.1 5500
The application would output:
["X", ["AF_INET", 61755, "localhost", "127.0.0.1"]] ["X", ["AF_INET", 61755, "localhost", "127.0.0.1"]] ["X", ["AF_INET", 61755, "localhost", "127.0.0.1"]] ["X", ["AF_INET", 61755, "localhost", "127.0.0.1"]] ["Hello APIdock\n", ["AF_INET", 61755, "localhost", "127.0.0.1"]]