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"
Nguồn
2016-01-07 17:25:39
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
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
Đó 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 ý. –