2016-01-07 31 views
7

Tôi không quá quen thuộc với Ruby, vì vậy tôi không thể tìm thấy tài liệu cho phương pháp này.TCPSocket # mỗi lần lặp lại trong ruby ​​là gì?

Khi gọi mỗi ngày một đối tượng TCPSocket, như thế này

require "socket" 

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

Có khối được gọi một lần cho mỗi gói tcp, một lần trên mỗi dòng (sau mỗi lần '\ n' char), một lần mỗi chuỗi (sau sau mỗi NUL/EOF), hoặc một cái gì đó khác hoàn toàn?

Trả lời

5

TL; DR TCPSocket.each sẽ lặp lại cho mỗi dòng mới được giới hạn \n chuỗi nhận được.

Thông tin chi tiết:

Một TCPSocket chỉ là một BasicSocket với một ít đường bột thêm trên đầu trang. Và một số BasicSocket là con của lớp học IO. Lớp IO chỉ là một luồng dữ liệu; do đó, nó có thể lặp lại được. Và that is where bạn có thể tìm thấy cách each được xác định cho TCPSocket.

Bật bảng điều khiển irb và nhập dòng mã của bạn bằng ổ cắm $stdin để xem cách each hoạt động. Cả hai đều được kế thừa từ IO. Dưới đây là một ví dụ về những gì sẽ xảy ra:

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

Nhưng để trực tiếp trả lời các câu hỏi, các khối được gọi là một lần mỗi \n nhân vật. Nếu khách hàng của bạn đang gửi dữ liệu 1 ký tự tại một thời điểm thì khối sẽ không được thực thi cho đến khi nó thấy \n.

Đây là một khách hàng mẫu nhanh chóng để hiển thị này:

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 

Và đây là những gì các máy chủ in ra:

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

Cũng lưu ý rằng các dấu phân cách có thể được thông qua như là một đối số (ví dụ ' thing.each (sep = "\ r \ n") '), hoặc đặt cho' IO # each' cùng với một vài phương thức khác bằng cách đặt '$ /', dấu phân cách mặc định chung, trừ khi thay đổi, mặc định thành ' \ n'. – Linuxios

+0

Câu trả lời tuyệt vời, nhưng tôi bị nhầm lẫn bởi câu cuối cùng: Nếu tôi gửi 1 byte/gói qua luồng TCP, thì đầu vào sẽ được đệm cho đến khi byte là '\ n' và chỉ sau đó được chuyển đến khối, phải không? – Benno

+0

Đó là chính xác @Benno, đầu vào sẽ được buff cho đến khi byte là ''\ n''. ** Sau đó ** khối 'mỗi' sẽ thực thi. Trừ khi bạn thay đổi hành vi mặc định đó như Linuxios đã lưu ý. –

Các vấn đề liên quan