Как предотвратить ошибку «Сброс соединения»? - PullRequest
1 голос
/ 06 января 2011

У меня очень простой TCP-сервер, реализованный на Ruby.В общем, он делает то, что должен, но время от времени я получаю «Ошибка подключения к серверу во время загрузки страницы» .У меня такое ощущение, что это как-то связано с close слишком быстрым разрывом соединения.Если да, то как мне ждать отправки всех данных?Или это что-то еще?

require 'socket'

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

Ответы [ 3 ]

2 голосов
/ 09 февраля 2011

Я не эксперт в этой области, но вот что, как мне кажется, происходит ....

Браузер отправляет GET-запрос с полем заголовка «Connection: keep-alive».Таким образом, браузер ожидает сохранения соединения по крайней мере до тех пор, пока не получит полный фрагмент ответа.В соответствии с этим протоколом ответ сервера должен включать заголовок, указывающий длину ответа, чтобы браузер знал, когда он получил полный ответ.После этой точки соединение может быть закрыто без заботы браузера.

Исходный пример слишком быстро закрывает соединение, прежде чем браузер сможет проверить получение полного ответа.Любопытно, что если я запускаю этот пример и обновляю свой браузер несколько раз, он будет загружаться примерно каждые 1 из 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 голос
/ 07 января 2011

Я подозреваю, что это связано с тем, что браузер ожидает HTTP-ответа с заголовками & c. Любопытно, что вы можете сделать так, чтобы ошибка «сброса» возникала каждый раз, если вы поставили перед «обеспечением» сон, скажем, одну секунду.

Как это исправить, зависит от того, что вы ищете. Если это не 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
0 голосов
/ 09 февраля 2011

Также следует отметить, что включение Connection: close в заголовок ответа, похоже, совсем не помогает мне с этой ошибкой сброса соединения в моем браузере (FFv3.6). Я должен включить оба поля заголовка content-length и метод sleep, чтобы задержать закрытие соединения, чтобы получить согласованный ответ в моем браузере.

...