Earlz
Earlz

Reputation: 63825

Socket.recv works but not gets or read?

Hello I've been messing around with Sockets in Ruby some and came across some example code that I tried modifying and broke. I want to know why it's broken.

Server:

require "socket"  
dts = TCPServer.new('127.0.0.1', 20000)  
loop do  
  Thread.start(dts.accept) do |s|  
  print(s, " is accepted\n")  
  s.write(Time.now)  
  print(s, " is gone\n")  
  s.close  
  end  
end  

Client that works:

require 'socket'  
streamSock = TCPSocket.new( "127.0.0.1", 20000 )  
streamSock.print( "Hello\n" )  
str = streamSock.recv( 100 )  
print str  
streamSock.close 

Client that is broken

require 'socket'  
streamSock = TCPSocket.new( "127.0.0.1", 20000 )  
streamSock.print( "Hello\n" )  
str=streamSock.read #this line modified
print str  
streamSock.close 

I know that the streamSock.print is unnecessary (as well as the naming scheme being non-ruby) but I don't understand why read doesn't work while recv does, Why is this?

Upvotes: 7

Views: 5380

Answers (1)

Pablo Castellazzi
Pablo Castellazzi

Reputation: 4184

A very subtle race condition. Your are closing the connection server side without waiting for the client to complete. If your client finish before s.close, you will get the right answer, if the server finish first, you will get Errno::ECONNRESET. Which mean the client lost the connection while working.

A simple workaround will be to wait a fixed amount of time before closing the connection server side. Just enough time to let the client finish.

Upvotes: 1

Related Questions