双向读取数据 TCPServer Ruby

问题描述

我是 Ruby 新手,我正在尝试设置 Tcpserver 和客户端,但是我无法将数据从客户端获取到服务器,因为客户端连接时由于某种原因,连接在 while 循环内被冻结。 代码如下:

server.rb

require "socket"
server = Tcpserver.new 1234
test = ""

loop do
  session = server.accept
  puts "Entering enter code herewhile loop."
  while line = session.gets
    puts "Inside while loop"
    test << line
  end
    puts "Finished reading data"

    puts "Data recieved - #{test}" # Read data from client
    session.write "Time is #{Time.Now}" # Send data to clent
    session.close
end

client.rb

require "socket"

socket = Tcpsocket.open("localhost",1234)
socket.puts "Sending data.." # Send data to server
while(line = socket.gets)
  puts line
end # Print sever response
socket.close

服务器打印“Inside while loop”一次,然后由于某种原因它从不打印“Finished reading data”,直到我手动结束客户端连接,在客户端结束连接后,服务器打印一切正常。我怎样才能使这段代码工作?谢谢!

解决方法

IO#gets 是一个阻塞调用。它等待来自底层 I/O 流的新行,或流的结尾。 (在这种情况下,它返回 nil

server.rb你有

while line = session.gets
  puts "Inside while loop"
  test << line
end

session.gets 从您的客户端读取一行,打印一些调试信息并将该行附加到 test。然后它尝试从客户端读取另一行

您的 client.rb 但是从不发送秒行,也不会关闭流。它发送一行:

socket.puts "Sending data.." # Send data to server

然后等待响应:

while(line = socket.gets)
  puts line
end

这永远不会发生,因为服务器正处于 while 循环中,等待来自客户端的更多数据。

您可以在发送完所有数据后调用 close_write 来解决此问题:

socket.puts "Sending data.." # Send data to server
socket.close_write           # Close socket for further writing

调用 close_write 而不是 close 允许您仍然从套接字读取。它还会导致服务器的 session.gets 返回 nil,因此它可以退出循环。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...