Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby TCPSocket: Find out how much data is available

Is there a way to find out how many bytes of data is available on an TCPSocket in Ruby? I.e. how many bytes can be ready without blocking?

like image 300
panzi Avatar asked Oct 21 '10 01:10

panzi


1 Answers

The standard library io/wait might be useful here. Requring it gives stream-based I/O (sockets and pipes) some new methods, among which is ready?. According to the documentation, ready? returns non-nil if there are bytes available without blocking. It just so happens that the non-nil value it returns it the number of bytes that are available in MRI.

Here's an example which creates a dumb little socket server, and then connects to it with a client. The server just sends "foo" and then closes the connection. The client waits a little bit to give the server time to send, and then prints how many bytes are avaiable for reading. The interesting stuff for you is in the client:

require 'socket'
require 'io/wait'

# Server

server_socket = TCPServer.new('localhost', 0)
port = server_socket.addr[1]
Thread.new do
  session = server_socket.accept
  sleep 0.5
  session.puts "foo"
  session.close
end

# Client

client_socket = TCPSocket.new('localhost', port)
puts client_socket.ready?    # => nil
sleep 1
puts client_socket.ready?    # => 4

Don't use that server code in anything real. It's deliberately retarded in order to keep the example simple.

Note: According to the Pickaxe book, io/wait is only available if "FIONREAD feature in ioctl(2)". Which it is in Linux. I don't know about Windows & others.

like image 181
Wayne Conrad Avatar answered Oct 03 '22 06:10

Wayne Conrad