1

我正在关注教程:http ://www.tutorialspoint.com/ruby/ruby_socket_programming.htm并使用它来设置“简单客户端”。

代码如下:

    require 'socket'      # Sockets are in standard library

    hostname = 'localhost'
    port = 2000

    s = TCPSocket.open(host, port)

    while line = s.gets   # Read lines from the socket
      puts line.chop      # And print with platform line terminator
    end
    s.close               # Close the socket when done

当我执行单个 s.gets 语句时,我从服务器获得了第一条响应行。当我再次执行 s.gets 时,我得到第二条响应行,等等。但是,当我到达响应结束并执行 s.gets 时,程序进入冻结状态。(如果我从 Rails 控制台测试上述程序)。当我运行代码时也会发生同样的情况 - 当 while 语句执行最终的 s.gets 时会发生冻结。关于如何解决这个问题的任何想法?

有关信息:服务器是使用以下 C# 代码发送响应消息的 C# 服务器(响应的每一行都使用相同的代码,并且响应中的最后一行与其他行没有任何区别):

    socket.Send(Encoding.ASCII.GetBytes(msg + "\r\n"));

所以我认为客户端冻结,因为它可能无法正确解释服务器的“响应结束”。有任何想法吗?

4

4 回答 4

2

从套接字读取 nil 值似乎存在问题。仍然不确定为什么会发生这种情况,但是在get () 中使用 Recovering from a broken TCP socket in Ruby 中建议的选择器可以很好地解决问题(会支持他的答案,但没有足够的代表)。

我遵循的解决方案是在方法中添加选择器,如下所示:

    def next_line_readable?(socket)
      readfds, writefds, exceptfds = select([socket], nil, nil, 0.1)
      p :r => readfds, :w => writefds, :e => exceptfds
      readfds #Will be nil if next line cannot be read
    end

然后在主程序中使用它:

    socket = TCPSocket.open(host, port)
    while next_line_readable?(socket)
      puts socket.gets.chop
    end
于 2012-06-07T08:13:33.317 回答
1

试试这个,我用 ruby​​ 编写一个 tcp 客户端和服务器

def sendto(str)
  begin
     socket.write(str)
    puts "Sent Message to:" +  socket.peeraddr[2]
  rescue Exception=>e
    puts red("Error Make sure the target is connected")
  end
end

检查它工作正常,直到 4 小时然后断开 与基于 ruby​​ 的服务器的连接

于 2012-09-26T07:09:06.453 回答
0

尝试使用socket.readorsocket.recvfrom方法而不是socket.gets.

这是相同的行为吗?

于 2012-06-06T17:04:27.687 回答
0

使用 recv 而不是 gets

   server = TCPServer.new 53492 # Server bound to port 53492
    loop do
      client = server.accept
      ansiString = client.recv(100).chomp
      client.puts result
      client.close
     end

您也可以将其转换为线程:

   server = TCPServer.new 53492 # Server bound to port 53492
   Thread.start(server.accept) do |client|
      loop do
        client = server.accept
        ansiString = client.recv(100).chomp
        client.puts result
        client.close
      end
    end
于 2019-07-19T08:31:12.677 回答