Socket.recv работает, но не получает или не читает? - PullRequest
5 голосов
/ 07 июня 2010

Здравствуйте, я немного возился с сокетами в Ruby и наткнулся на пример кода, который я попытался изменить и сломал.Я хочу знать, почему он сломан.

Сервер:

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  

Клиент, который работает:

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

Клиент, который сломан

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

Я знаю, что streamSock.print не нужен (так же как схема именования не является ruby), но я не понимаю, почему read не работает, в то время как recv, Почему это?

1 Ответ

0 голосов
/ 19 мая 2011

Очень тонкое состояние гонки. Вы закрываете сторону сервера соединений, не дожидаясь завершения клиента. Если ваш клиент завершит работу до s.close, вы получите правильный ответ, если сервер завершит работу первым, вы получите Errno :: ECONNRESET Это означает, что клиент потерял соединение во время работы.

Простой обходной путь - подождать фиксированное количество времени перед закрытием стороны сервера соединений. Достаточно времени, чтобы позволить клиенту закончить.

...