Reputation: 63825
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
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