From: Eric Wong Date: 2015-12-16T10:43:42+00:00 Subject: [ruby-core:72184] EOF behavior for socket recv* methods? Background: IO#read with length arg returns nil on EOF; and read_nonblock raises EOFError or returns nil depending on how the `exception' keyword is specified: a, b = IO.pipe b.close p a.read(1) # => nil p begin; a.read_nonblock(1); rescue => e; e; end # => nil EOFError p a.read_nonblock(1, exception: false) # => nil However, using the analogous recv/recv_nonblock calls return an empty string, similar to IO#read w/o length arg... require 'socket' a, b = UNIXSocket.pair(:SEQPACKET) b.close p a.recv(1) # => "" p a.recv_nonblock(1) # => "" p a.recv_nonblock(1, exception: false) # => "" I've noticed this for many years and always forgot to bring it up, but what was the reasoning for this? In any case, I'm not sure if we can change it at this point. This mistake (if it was one) has been with us for many years. Linux manpage for recv/recvfrom/recvmsg says: RETURN VALUE These calls return the number of bytes received, or -1 if an error occurred. The return value will be 0 when the peer has performed an orderly shutdown. So the same thing as read(2)...