class BasicSocket
Socket extensions for buffering support.
Definitions
def ip_protocol_tcp?
Check if this socket uses TCP protocol.
Signature
-
returns
Boolean
True if the socket is TCP over IPv4 or IPv6.
Implementation
def ip_protocol_tcp?
local_address = self.local_address
return (local_address.afamily == ::Socket::AF_INET || local_address.afamily == ::Socket::AF_INET6) && local_address.socktype == ::Socket::SOCK_STREAM
end
def buffered?
Check if the socket is buffered.
Signature
-
returns
Boolean
True if the socket is buffered.
Implementation
def buffered?
return false unless super
if ip_protocol_tcp?
return !self.getsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY).bool
else
return true
end
end
def buffered=(value)
Set the buffered state of the socket.
Signature
-
parameter
value
Boolean
True to enable buffering, false to disable.
Implementation
def buffered=(value)
super
if ip_protocol_tcp?
# When buffered is set to true, TCP_NODELAY shold be disabled.
self.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, value ? 0 : 1)
end
rescue ::Errno::EINVAL
# On Darwin, sometimes occurs when the connection is not yet fully formed. Empirically, TCP_NODELAY is enabled despite this result.
rescue ::Errno::EOPNOTSUPP
# Some platforms may simply not support the operation.
end
def readable?
Check if the socket is readable.
Signature
-
returns
Boolean
True if the socket is readable.
Implementation
def readable?
# If we can wait for the socket to become readable, we know that the socket may still be open.
result = self.recv_nonblock(1, ::Socket::MSG_PEEK, exception: false)
# No data was available - newer Ruby can return nil instead of empty string:
return false if result.nil?
# Either there was some data available, or we can wait to see if there is data avaialble.
return !result.empty? || result == :wait_readable
rescue Errno::ECONNRESET, IOError
# This might be thrown by recv_nonblock.
return false
end