Class: BasicSocket

Inherits:
Object
  • Object
show all
Defined in:
lib/io/stream/shim/buffered.rb,
lib/io/stream/shim/readable.rb

Overview

Socket extensions for buffering support.

Instance Method Summary collapse

Instance Method Details

#buffered=(value) ⇒ Object

Set the buffered state of the socket.



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/io/stream/shim/buffered.rb', line 49

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

#buffered?Boolean

Check if the socket is buffered.

Returns:

  • (Boolean)


37
38
39
40
41
42
43
44
45
# File 'lib/io/stream/shim/buffered.rb', line 37

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

#ip_protocol_tcp?Boolean

Check if this socket uses TCP protocol.

Returns:

  • (Boolean)


29
30
31
32
33
# File 'lib/io/stream/shim/buffered.rb', line 29

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

#readable?Boolean

Check if the socket is readable.

Returns:

  • (Boolean)


23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/io/stream/shim/readable.rb', line 23

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