2016-01-07 15 views
7

Ich bin nicht vertraut mit Ruby, also konnte ich die Dokumentation für diese Methode nicht finden.Was passiert mit TCPSocket # in Ruby?

Wenn jeder auf einem TCPSocket Objekt aufgerufen wird, wie diese

require "socket" 

srv = TCPServer.new("localhost", 7887) 
skt = srv.accept 
skt.each {|arg| p arg} 

Hat der Block einmal pro TCP-Paket aufgerufen, einmal pro Zeile (nach jedem ‚\ n‘ char), einmal pro String (nach nach jedes NUL/EOF), oder etwas ganz anderes?

Antwort

5

TL; DR TCPSocket.each iteriert für jede durch Zeilenbegrenzung getrennte Zeichenfolge \n, die es empfängt.

Weitere Details:

A TCPSocket ist nur ein BasicSocket mit einigen zusätzlichen Puderzucker oben drauf. Und ein BasicSocket ist ein Kind der IO Klasse. Die IO Klasse ist nur ein Datenstrom; somit ist es iterierbar. Und that is where finden Sie, wie each für TCPSocket definiert ist.

Feuer eine irb Konsole und geben Sie Ihre Codezeile mit der $stdin Buchse, um zu sehen, wie each verhält. Beide erben von IO. Hier ist ein Beispiel dafür, was passiert:

irb(main):011:0> $stdin.each {|arg| p arg + "."} 
hello 
"hello\n." 

Aber, um direkt die Frage zu beantworten, der Block einmal pro \n Charakter genannt wird. Wenn Ihr Client Daten jeweils 1 Zeichen gleichzeitig sendet, wird der Block erst ausgeführt, wenn er \n sieht.

Hier ist eine kurze Probe Client dies zeigen:

irb(main):001:0> require 'socket' 
=> true 
irb(main):002:0> s = TCPSocket.open("localhost", 7887) 
=> #<TCPSocket:fd 9> 
irb(main):003:0> s.puts "hello" 
=> nil 
irb(main):007:0> s.write "hi" 
=> 2 
irb(main):008:0> s.write ", nice to meet you" 
=> 18 
irb(main):009:0> s.write "\n" 
=> 1 

Und hier ist das, was der Server ausgedruckt:

"hello\n" 
"hi, nice to meet you\n" # note: this did not print until I sent "\n" 
+1

Beachten Sie auch, dass der Separator als Argument übergeben werden können (zB ' thing.each (sep = "\ r \ n") ') oder für' IO # each' zusammen mit ein paar anderen Methoden setzen, indem man '$ /', das globale Standard-Trennzeichen, das, wenn nicht geändert, standardmäßig auf 'setzt \ n'. – Linuxios

+0

Große Antwort, aber ich bin verwirrt durch den letzten Satz: Wenn ich 1 Byte/Paket über einen TCP-Stream senden, dann würde die Eingabe zwischengespeichert werden, bis das Byte '\ n' ist und nur dann an den Block übergeben, richtig? – Benno

+0

Das ist richtig @Benno, die Eingabe würde aufgeraut werden, bis das Byte '' \ n'' ist. ** Dann ** wird der 'each' Block ausgeführt. Es sei denn, Sie ändern dieses Standardverhalten, wie Linuxios bemerkt. –