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

私はこの分野の専門家ではありませんが、これが起こっていると私が信じていることです。

ブラウザは、ヘッダーフィールド「接続:キープアライブ」を使用して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応答を期待しているためだと思います。不思議なことに、たとえば1秒間のスリープを「保証」する前に置くと、毎回「リセット」エラーが発生する可能性があります。

それを修正する方法は、あなたが何を求めているかによって異なります。これが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
于 2011-01-06T21:05:41.507 に答える
0

また、応答ヘッダーに含めることConnection: closeは、ブラウザ(FFv3.6)でのこの接続リセットエラーではまったく役に立たないように思われることに注意してください。ブラウザで一貫した応答を得るには、content-lengthヘッダーフィールドと、接続を閉じるのを遅らせるメソッドの両方を含める必要があります。sleep

于 2011-02-09T12:35:33.253 に答える