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 connection is freezed inside the while loop. Here is the code:
server.rb
require "socket"
server = TCPServer.new 1234
test = ""
loop do
session = server.accept
puts "Entering enter code herewhile loop."
while line = session.gets
puts "Inside while loop"
test << line
end
puts "Finished reading data"
puts "Data recieved - #{test}" # Read data from client
session.write "Time is #{Time.now}" # Send data to clent
session.close
end
client.rb
require "socket"
socket = TCPSocket.open("localhost", 1234)
socket.puts "Sending data.." # Send data to server
while(line = socket.gets)
puts line
end # Print sever response
socket.close
The server prints "Inside while loop" one time, and then for some reason it never prints "Finished reading data" until I manually end the client connection, after the client ends the connection the server prints everything OK. How can I make this code work? Thanks!
IO#gets
is a blocking call. It waits for either a new line from the underlying I/O stream, or the end of the stream. (in which case it returns nil
)
In server.rb you have
while line = session.gets
puts "Inside while loop"
test << line
end
session.gets
reads one line from your client, prints some debug info and appends the line to test
. It then attempts to read another line from the client.
Your client.rb however never sends a seconds line, nor does it close the stream. It sends a single line:
socket.puts "Sending data.." # Send data to server
and then waits for a response:
while(line = socket.gets)
puts line
end
which never comes because the server is sitting in the while
loop, waiting for more data from the client.
You can solve this by calling close_write
after all data has been sent:
socket.puts "Sending data.." # Send data to server
socket.close_write # Close socket for further writing
Calling close_write
instead of close
allows you to still read from the socket. It will also cause the server's session.gets
to return nil
, so it can get out of its loop.