我正在关注教程: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#代码发送响应消息(响应的每一行使用相同的代码,并且响应中的最后一行与其他行的处理方式不同): / p>
socket.Send(Encoding.ASCII.GetBytes(msg + "\r\n"));
所以我认为客户端冻结,因为它可能无法解释服务器"响应结束"正常。有什么想法吗?
答案 0 :(得分:2)
从套接字读取nil值似乎有问题。仍然不确定为什么会发生这种情况,但使用Recovering from a broken TCP socket in Ruby when in gets()中建议的选择器可以非常好地解决问题(可能会提出他的答案,但没有足够的代表)。
我遵循的解决方案是在方法中添加选择器,如下所示:
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
答案 1 :(得分:0)
尝试使用socket.read
或socket.recvfrom
方法代替socket.gets
。
这是一样的行为吗?
答案 2 :(得分:0)
试试这个在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小时然后断开连接 Connection to ruby based server
答案 3 :(得分:0)
使用recv代替获取
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