2010-06-07 1 views
5

Bonjour, j'ai fait des bêtises avec Sockets dans Ruby et je suis tombé sur un exemple de code que j'ai essayé de modifier et que j'ai cassé. Je veux savoir pourquoi c'est cassé.Socket.recv fonctionne mais ne pas obtenir ou lire?

Serveur:

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 qui fonctionne:

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

client qui est cassé

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

Je sais que le streamSock.print est inutile (ainsi que le schéma de nommage être non-ruby) mais je ne comprends pas pourquoi read ne fonctionne pas pendant que recv fait, Pourquoi est-ce?

+0

Si quelqu'un attrapé que dans l'exemple cassé j'avais une adresse IP différente. ne pas tenir compte de cela, j'ai oublié de le changer lors du copier-coller – Earlz

+0

Jetez un oeil à cette question connexe: http://stackoverflow.com/questions/1147852/ruby-tcpsocket-write-doesnt-work-but-puts-does –

+0

Les deux Vos clients fonctionnent bien pour moi. Je suis sur OS X Snow Leopard. – Hongli

Répondre

0

Une condition de course très subtile. Vous fermez le côté serveur de connexion sans attendre que le client se termine. Si votre client termine avant s.close, vous obtiendrez la bonne réponse, si le serveur termine en premier, vous obtiendrez Errno :: ECONNRESET. Ce qui signifie que le client a perdu la connexion en travaillant. Une solution de contournement simple consistera à attendre une durée fixe avant de fermer le côté du serveur de connexion. Juste le temps de laisser le client finir.

Questions connexes