How to read from a TCPServer socket in ruby using read, readpartial and read_nonblock

2012-11-24T01:14:58

I have a 2 part question on reading from sockets and how is it managed on Ruby servers like Unicorn or Mongrel

  1. I've learnt that to read from a socket is different from reading a file and that there are no distinct EOF message sent and the data is an endless stream. So how do you know when to stop reading? My TCPServer for example in this case when I hit my server by accessing http://localhost:9799 from a browser, it hangs after there is no more data to read and it won't throw the EOFError either.

require 'socket'

READ_CHUNK = 1024
socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM)
addr = Socket.pack_sockaddr_in(9799, '127.0.0.1')
socket.bind(addr)
socket.listen(Socket::SOMAXCONN)
socket.setsockopt(:SOCKET, :REUSEADDR, true)

puts "Server is listening on port = 9799"
loop do 
    connection, addr_info = socket.accept
    data_buffer = ""

    loop do
        begin
            connection.read_nonblock(READ_CHUNK, data_buffer)
            puts "Buffer = #{data_buffer}"
        rescue Errno::EAGAIN => e
            IO.select([connection])         
            retry
        rescue EOFError
            break
        end
    end
    connection.write("HTTP/1.1 200 \r\n")
    connection.write("Content-Type: text/html\r\n")
    connection.write("Status 200 \r\n")
    connection.write("Connection: close \r\n")
    connection.write("Hello World \r\n")
    connection.close
end

I'd like to know whats the best practice/standard approach used by Ruby servers. I see the Unicorn uses read_nonblock from kgio library and mongrel uses readpartial (I'm not sure about these but going through the code this is what I feel is the approach adopted.) Even with checks for \r\n how does the server know the input is complete. Could explain how this should be done (and I think gets is not the approach - its with read, readpartial, read_nonblock).

2). I would really appreciate a few lines on how this is achieved in servers like unicorn or passenger

Thank you.

Copyright License:
Author:「Sid」,Reproduced under the CC 4.0 BY-SA copyright license with link to original source & disclaimer.
Link to:https://stackoverflow.com/questions/13533382/how-to-read-from-a-tcpserver-socket-in-ruby-using-read-readpartial-and-read-non

About “How to read from a TCPServer socket in ruby using read, readpartial and read_nonblock” questions

I have a 2 part question on reading from sockets and how is it managed on Ruby servers like Unicorn or Mongrel I've learnt that to read from a socket is different from reading a file and that ther...
I'm trying to understand and recreate a simple preforking server along the lines of unicorn where the server on start forks 4 processes which all wait (to accept) on the controlling socket. The
I am trying to send a request to a TCPServer I created, read the request, and eventually write it to a file I am creating. It works some of the time, but times out often. This then causes the s...
im building a small game in ruby to practice programming, so far everything has went well but im trying to implement multiplayer support, i can connect to the server and i can send information but ...
im new in Ruby and Im trying to set up a TCPServer and a Client, but Im having trouble getting the data from the client to the server because for some reason when the client connects, the connectio...
I'm creating a ruby server which is connecting to a TCP client. My server is using a TCPServer and I'm attempting to use TCPServer::recv(), but it doesn't wait for data, so just continues in a tight
I am trying to understand how the IO.pipe in Ruby works, In the example below, I send data to the io pipe and close the stream after I finish sending the data. In a child process, I read the data u...
I'm trying to add error logging to a JRuby process that reads data from stdout of one subprocess, and writes this data to stdin of another subprocess, while collecting some statistics on the data. ...
i want to get the IP Address of the client in a TCPServer in Ruby. And (if it is possible) the MAC Address. For example, a Time Server in Ruby, see the comment. tcpserver = TCPServer.new("", 80) if
Suppose I have a select loop with some open connections that I'm going to read from and I have state machines attached to each connection that are meant to parse some stuff coming over the wire and...

Copyright License:Reproduced under the CC 4.0 BY-SA copyright license with link to original source & disclaimer.