1

我有一个用 Ruby 实现的非常基本的 TCP 服务器。一般来说,它会做它应该做的事情,但每隔一段时间我就会收到“在页面加载时重置与服务器的连接”错误。我有一种感觉,这与close过早终止连接有关。如果是这样,我如何等待发送所有数据?或者是别的什么?

require 'socket'

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

3 回答 3

2

我不是这方面的专家,但这是我认为正在发生的事情......

浏览器发送一个带有标题字段“Connection: keep-alive”的 GET 请求。因此,浏览器希望至少在收到完整的响应块之前保持连接处于活动状态。在此协议下,服务器响应必须包含一个标头,指定响应的长度,以便浏览器知道它何时收到完整的响应。在此之后,可以在浏览器不关心的情况下关闭连接。

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

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

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
于 2011-02-09T06:16:35.017 回答
1

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

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

#!/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
于 2011-01-06T21:05:41.507 回答
0

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

于 2011-02-09T12:35:33.253 回答