2016-01-07 34 views
7

我對Ruby不太熟悉,所以我無法找到這個方法的文檔。TCPSocket#每次在ruby中重複執行什麼操作?

當調用每一個的TCPSocket對象上,這樣

require "socket" 

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

是否塊獲得每個TCP包調用一次,每行(後每個「\ n」字符),一旦每串(後一次之後每個NUL/EOF),還是完全不同的東西?

回答

5

TL; DR TCPSocket.each將迭代每個換行符分隔\n它接收的字符串。

更多細節:

一個TCPSocket只是一個BasicSocket,頂部一些額外的粉末糖。而BasicSocketIO類的孩子。 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" 
+1

還要注意的是,隔板可以作爲參數傳遞(如' thing.each(sep =「\ r \ n」)'),或者通過設置全局默認分隔符$ /來爲每個IO#設置一些其他方法,除非改變,否則默認爲' \ N'。 – Linuxios

+0

很好的答案,但我最後一句話感到困惑:如果我通過TCP流發送1個字節/數據包,那麼輸入將被緩衝,直到字節爲'\ n',然後才傳遞給該塊,對吧? – Benno

+0

這是正確的@Benno,輸入將被拋光,直到字節爲'\ n''。 **然後**將執行'each'塊。除非您像Linuxios指出的那樣更改默認行爲。 –

相關問題