时间:2011-01-06 19:52:29

标签: ruby sockets networking tcpserver

我有一个用Ruby实现的非常基本的TCP服务器。一般情况下,它会按预期执行,但每隔一段时间我就会得到“在页面加载时重置与服务器的连接”错误。我觉得它与close过早终止连接有关。如果是这样,我如何等待发送所有数据?还是别的什么?

require 'socket'

server = TCPServer.new('', 80)
loop do
    session = server.accept
    begin
        session.print Time.now
    ensure
        session.close
    end
end

3 个答案:

答案 0 :(得分:2)

我不是这方面的专家,但我认为这就是我所发生的......

浏览器发送带有标题字段“Connection:keep-alive”的GET请求。因此,浏览器期望保持连接至少存在,直到它收到完整的响应块为止。在此协议下,服务器响应必须包含指定响应长度的标头,以便浏览器知道何时收到完整响应。在此之后,可以在没有浏览器关注的情况下关闭连接。

原始示例在浏览器验证收到完整响应之前,过快地关闭了连接。奇怪的是,如果我运行该示例并多次刷新我的浏览器,它将大约每10次尝试加载一次。也许这种不稳定的行为是由于浏览器偶尔执行速度足以击败我的服务器关闭连接。

以下是在我的浏览器中一致执行的代码示例:

require 'socket'

response = %{HTTP/1.1 200 OK
Content-Type: text;charset=utf-8
Content-Length: 12

Hello World!
}

server = TCPServer.open(80)

loop do
  client = server.accept
  client.puts response
  sleep 1
  client.close
end

答案 1 :(得分:1)

我怀疑这是因为浏览器期望带有标题& c的HTTP响应。奇怪的是,如果你在“确保”睡眠之前,你可以每次都发生“重置”错误。比如,一秒钟。

如何解决这个问题取决于你所追求的目标。如果这不是HTTP服务器,则不要使用浏览器进行测试。相反,使用telnet或编写一个小程序。如果它是一个HTTP服务器,那么看一下内置于Ruby MRI> = 1.8的webrick。方法如下:

#!/usr/bin/ruby1.8

require 'webrick'

# This class handles time requests

class TimeServer < WEBrick::HTTPServlet::AbstractServlet

  def do_GET(request, response)
    response.status = 200
    response['Content-Type'] = 'text/plain'
    response.body = Time.now.to_s
  end

end

# Create the server.  There are many other options, if you need them.
server = WEBrick::HTTPServer.new(:Port=>8080)

# Whenever a request comes in for the root page, use TimeServer to handle it
server.mount('/', TimeServer)

# Finally, start the server.  Does not normally return.
server.start

答案 2 :(得分:0)

此外,请注意,在我的浏览器(FFv3.6)中,在响应标头中包含Connection: close似乎对我的连接重置错误没有任何帮助。我必须同时包含content-length标头字段,并包含sleep方法,以便在连接关闭时加入一些延迟,以便在浏览器中获得一致的响应。