2016-01-07 9 views
7

私はあまりRubyに慣れていないので、このメソッドのドキュメントを見つけることができませんでした。このルビーでTCPSocket#は何回繰り返しますか?

require "socket" 

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

のように、TCPSocketオブジェクト上の各を呼び出すときにブロックが一度ライン毎(各「\ n」の文字の後)、一度文字列あたり(後にした後、TCPパケットごとに一度呼び出されますん

各NUL/EOF)、または完全に異なるものはありますか?

答えて

5

TL; DR TCPSocket.eachは、それが受け取る改行文字ごとに改行を繰り返します。

詳細:

TCPSocketは上にいくつかの余分な粉砂糖とちょうどBasicSocketです。 BasicSocketは、IOクラスの子です。 IOクラスは単なるデータストリームです。したがって、iterableです。 that is whereeachTCPSocketのために定義されている方法を見つけることができます。

irbコンソールを起動し、$stdinソケットでコード行を入力して、eachの動作を確認します。彼らは両方ともIOから継承します。

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

しかし、直接の質問に答えるために、ブロックは\n文字ごとに一度呼び出されます。ここでは何が起こるかの例があります。クライアントが一度に1文字ずつデータを送信している場合、ブロックは\nが表示されるまで実行されません。ここで

はこれを示すために迅速なサンプルのクライアントである:

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 

そして、ここでは、サーバーをプリントアウトするものである:

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

はまた、セパレータは、引数(例えば 'として渡すことができることに注意してくださいデフォルトのセパレータである '$ /'を設定することで、 'IO#each 'と他のいくつかのメソッドを設定します。デフォルトのセパレータは変更されない限り' \ n \。 – Linuxios

+0

偉大な答えが、私は最後の文で混乱している:私はTCPストリームを介して1バイト/パケットを送信する場合は、入力が '\ n'までブロックされ、ブロックに渡されるまで、バッファリングされますか? – Benno

+0

これは正しい@Bennoですが、入力は ''\ n'''までbuffedされます。 **その後** 'each'ブロックが実行されます。 Linuxiosが指摘しているように、デフォルトの動作を変更しない限り。 –

関連する問題