2011-01-06 16 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レスポンス(ヘッダーが&)を期待していると思われます。奇妙なことに、「リセット」エラーは毎回、例えば1秒のスリープを「確実に」確保する前に行うことができます。

修正方法は、後で何をするかによって異なります。これがHTTPサーバーでない場合は、ブラウザを使用してテストしないでください。代わりに、telnetを使うか、少しのプログラムを書いてください。 HTTPサーバである場合は、Ruby MRI> = 1.8に組み込まれているwebrickを見てください。ここでは、方法は次のとおりです。

ブラウザがヘッダフィールドでGETリクエストを送信します....私はこの分野での専門家ではないんだけど、ここで私が起こっていると考えているものです

#!/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

「接続:キープ「有効」。したがって、ブラウザは少なくとも応答の完全なチャンクを受信するまで接続を維持することを期待しています。このプロトコルの下では、サーバーの応答には、応答の長さを指定するヘッダーが含まれていなければならないため、ブラウザーは完全な応答を受信した時点を知る必要があります。この後、ブラウザを介さずに接続を閉じることができます。

元の例では、ブラウザが完全な応答を受け取ったことを検証する前に、接続が短時間で終了しています。不思議なことに、そのサンプルを実行してブラウザを数回リフレッシュすると、約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メソッドを含めると、ブラウザで一貫性のある応答を得るために接続を閉じる際に遅延が生じます。

関連する問題