2009-07-18 5 views
6

Tôi đang làm việc trên ứng dụng khách/máy chủ Ruby TCP bằng cách sử dụng GServer và TCPSocket. Tôi đã gặp phải một vấn đề mà tôi không hiểu. Ứng dụng khách TCPSocket của tôi kết nối thành công với Máy chủ GS của tôi, nhưng tôi chỉ có thể gửi dữ liệu bằng cách sử dụng các lần đặt. Các cuộc gọi tới TCPSocket.send hoặc TCPSocket.write không làm gì cả. Có một số phép thuật mà tôi đang thiếu?Ruby TCPSocket viết không hoạt động, nhưng đặt không?

tcp_client = TCPSocket.new(ipaddr, port) 
tcp_client.puts('Z') # -> GServer receives "Z\n" 

Nhưng nếu tôi sử dụng ghi hoặc gửi ...

tcp_client = TCPSocket.new(ipaddr, port) 
tcp_client.write('Z') # -> nothing is received 
tcp_client.send('Z') # -> nothing is received 

Thanks for the help

thông tin bổ sung:

  1. Hành vi này là như nhau trên Linux & của Windows .
  2. Xối rửa ổ cắm sau khi ghi không làm thay đổi hành vi.

Trả lời

4

Bạn có chắc chắn rằng sự cố không nằm ở phía máy chủ không? Bạn đang sử dụng một số phương pháp để đọc mà mong đợi một chuỗi hoặc một cái gì đó kết thúc trong "\ n"?

+0

Tôi nghĩ rằng tôi đã sử dụng recvfrom cho phía máy chủ, nhưng hóa ra tôi đã sử dụng được, đó là tìm kiếm các ký tự dòng mới. – nathan

2

Hãy thử xả nước một cách rõ ràng:

tcp_client = TCPSocket.new(ipaddr, port) 
tcp_client.write('Z') 
tcp_client.send('Z') 
tcp_client.flush 

Bằng cách này, đầu ra là đệm tại hầu hết chỉ đến điểm mà tại đó bạn quyết định nó nên được gửi đi.

+1

Cảm ơn brad, nhưng xem bình luận của tôi ở trên. Không có sự khác biệt khi gọi tuôn ra. – nathan

3

Với việc lưu vào bộ đệm được lưu trong các bài đăng trước để giải quyết câu hỏi liệu dữ liệu có đang được gửi hay không, hãy xem xét ghi lại dữ liệu trên đường bằng cách sử dụng một cái gì đó như wireshark. Nếu dữ liệu bạn đang gửi được nhìn thấy trên dòng thì máy chủ không nhận được dữ liệu đó.

Nếu không, nếu dữ liệu không đi vào dòng, TCP có thể giữ dữ liệu để tránh gửi một đoạn đơn với chỉ một vài byte trong đó (see Nagle's Algorithm). Tùy thuộc vào hệ điều hành hoặc nhà cung cấp TCP của bạn, bạn có thể có hành vi khác nhau, nhưng hầu hết các ngăn xếp TCP hỗ trợ tùy chọn TCP_NODELAY có thể giúp dữ liệu ra một cách kịp thời hơn.

tcp_client.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) 

Điều này có thể giúp gỡ lỗi, nhưng thường không được để trong mã sản xuất nếu thông lượng ưu tiên cao hơn phản hồi.

+1

netcat là một công cụ rất hữu ích cũng như cho mục đích thử nghiệm. "nc -v -n -l -p 12345" sẽ tạo một máy chủ nghe trên cổng 12345 sẽ in dữ liệu ngay lập tức khi nhận được. –

+0

'-l Đó là lỗi khi sử dụng tùy chọn này cùng với các tùy chọn -p, -s hoặc -z' – 7stud

0

Xin chào, lý do nên liên quan đến thực tế đặt thêm LF và CRL tự động vào chuỗi của bạn. Nếu bạn muốn sử dụng gửi hoặc viết bạn cần phải thêm chúng mình để ví dụ đó sẽ là:

tcp_client.send ("Z \ r \ n", 0)

0

tôi đã cùng một vấn đề, vì vậy sau khi đọc ổ cắm, tôi phải xóa rõ ràng trường hợp cuối cùng của "\ n" bằng cách làm như sau:

client_socket.gets.gsub(/\n$/, '')