2011-01-06 3 views
1

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

require 'socket' 

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

ответ

1

Я подозреваю, что это потому, что браузер ожидает ответа 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 
+0

Спасибо. Я уже играю с ним, и он не генерирует эту ошибку. Мне все еще интересно, хотя исходный пример может быть исправлен. В C# можно вызвать 'Close' в сокете с таймаутом и устранить ту же проблему в мире .NET. – detunized

+1

@detunized, я смущен, чтобы сказать, что не знаю. Надеюсь, кто-то придет и поможет нам обоим. –

+1

Хотя это не отвечает на мой первоначальный вопрос, спасибо за обмен мыслями. В конце концов, я все равно это делал. Все равно было бы интересно узнать, почему это происходит и как его предотвратить. – detunized

2

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

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

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

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

Смежные вопросы