TL; DR TCPSocket.each
將迭代每個換行符分隔\n
它接收的字符串。
更多細節:
一個TCPSocket
只是一個BasicSocket
,頂部一些額外的粉末糖。而BasicSocket
是IO
類的孩子。 IO
類只是一個數據流;因此,它是可迭代的。和that is where你可以找到each
定義爲TCPSocket
。
啓動一個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"
還要注意的是,隔板可以作爲參數傳遞(如' thing.each(sep =「\ r \ n」)'),或者通過設置全局默認分隔符$ /來爲每個IO#設置一些其他方法,除非改變,否則默認爲' \ N'。 – Linuxios
很好的答案,但我最後一句話感到困惑:如果我通過TCP流發送1個字節/數據包,那麼輸入將被緩衝,直到字節爲'\ n',然後才傳遞給該塊,對吧? – Benno
這是正確的@Benno,輸入將被拋光,直到字節爲'\ n''。 **然後**將執行'each'塊。除非您像Linuxios指出的那樣更改默認行爲。 –