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"
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
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
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. –