2009-07-18 9 views
6

Sto lavorando a un'applicazione client/server TCP Ruby usando GServer e TCPSocket. Ho incontrato un problema che non capisco. Il mio client TCPSocket si collega correttamente al mio GServer, ma posso solo inviare dati usando puts. Le chiamate a TCPSocket.send o TCPSocket.write non fanno nulla. C'è qualche magia che mi manca?Ruby TCPSocket write non funziona, ma puts fa?

tcp_client = TCPSocket.new(ipaddr, port) 
tcp_client.puts('Z') # -> GServer receives "Z\n" 

Ma se io uso di scrittura o mando ...

tcp_client = TCPSocket.new(ipaddr, port) 
tcp_client.write('Z') # -> nothing is received 
tcp_client.send('Z') # -> nothing is received 

Grazie per l'aiuto

Ulteriori informazioni:

  1. Il comportamento è lo stesso su Linux & di Windows .
  2. Il lavaggio della presa dopo la scrittura non modifica il comportamento.

risposta

4

Sei sicuro che il problema non sia sul lato server? Stai usando un metodo per leggere che si aspetta una stringa o qualcosa che termina in "\ n"?

+0

Pensavo di aver usato recvfrom per il lato server, ma è risultato che stavo usando gets, che sta cercando il carattere newline. – nathan

2

Prova esplicitamente vampate di calore:

tcp_client = TCPSocket.new(ipaddr, port) 
tcp_client.write('Z') 
tcp_client.send('Z') 
tcp_client.flush 

In questo modo, l'uscita viene tamponata al massimo solo fino al punto in cui si decide che deve essere inviato fuori.

+1

Grazie brad, ma vedere il mio commento sopra. Non c'era differenza quando si chiamava flush. – nathan

3

Con il buffering curato nei post precedenti per rispondere alla domanda se i dati vengono inviati, prendere in considerazione l'acquisizione dei dati sulla linea utilizzando qualcosa come wireshark. Se i dati che si stanno inviando vengono visualizzati sulla linea, il server non li riceve.

Altrimenti, se i dati non vanno sulla linea, TCP può trattenere i dati per evitare di inviare un singolo segmento con solo pochi byte (see Nagle's Algorithm). A seconda del tuo OS o del tuo fornitore di TCP, potresti avere un comportamento diverso, ma la maggior parte degli stack TCP supporta l'opzione TCP_NODELAY che potrebbe aiutare a ottenere i dati in modo più tempestivo.

tcp_client.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) 

questo può aiutare il debug, ma in genere non dovrebbero essere lasciati nel codice di produzione se il throughput è una priorità maggiore rispetto reattività.

+1

netcat è uno strumento molto utile anche per scopi di test. "nc -v -n -l -p 12345" creerà un server di ascolto sulla porta 12345 che stamperà i dati immediatamente mentre lo riceve. –

+0

'-l È un errore usare questa opzione insieme alle opzioni -p, -s, o -z' – 7stud

0

Ciao là il motivo dovrebbe essere correlato al fatto mette aggiungere automatico LF e CRL alla stringa. Se si desidera utilizzare la trasmissione o scrivere è necessario aggiungere voi stessi così per esempio che sarebbe:

tcp_client.send ("Z \ r \ n", 0)

0

Ho avuto lo stesso problema, quindi dopo aver letto il socket, ho dovuto eliminare esplicitamente l'ultima istanza di "\ n" facendo quanto segue:

client_socket.gets.gsub(/\n$/, '') 
Problemi correlati