2011-07-08 24 views
3

が「TCPによる接続をリセットする」エラーが発生しました。以下のコードは、TCPサーバーとクライアントの作成を目的としています。 しかし、クライアントスレッドの数が多すぎると(たとえば、100スレッド)、クライアントは「ピアによって接続がリセットされました」というエラーを受け取ります。私はエラーの原因を見つけることができないので、私はあなたの助けが必要です。新しいtcpソケット

サーバー:

#!/usr/bin/env ruby1.9 
# -*- coding: utf-8 -*- 

require "socket" 
crab = TCPServer.new "127.0.0.1", 8087 
while browser = crab.accept 
    Thread.new browser do | client | 
    puts client.gets 
    client.puts "hello" 
    client.close 
    end 
end 

クライアント:

#!/usr/bin/env ruby1.9 
# -*- coding: utf-8 -*- 
require "socket" 
threads_arr = [] 
ARGV[0].to_i.times do  
    t = Thread.new do 
    client = TCPSocket.new "127.0.0.1", 8087 
    client.puts "hello" 
    client.gets 
    client.close 
    end 
    threads_arr << t 
end 
threads_arr.each do | t | 
    t.join 
end 

Envrionment:

のMac OS X 10.6.8

ルビー1.8.7p174 /ルビー1.9.2p180

答えて

3

これはEventMachineで簡単にできますか?スレッディングは、問題を引き起こし始める前に、これまでにスケーリングするだけです。 EventMachineは、多数の接続を受け取るときの負荷をより良く処理します。

受け入れキューが十分に大きいかどうかを確認する必要があります。デフォルトは保留中の5つの接続のようなもので、十分早く確認できない場合は、それらを削除した可能性があります。

+0

私が見るには、問題はバックログが小さすぎるということでした。 – lululau

0

ソケット接続は、片面のみ、またはクライアントのみ、またはサーバーのみを閉じてください。あなたの例では、サーバー接続の接続が最初のクライアントは、接続を試みるときに例外を受信する場合。
は、クライアントの例close呼び出しのために削除:

t = Thread.new do 
    client = TCPSocket.new "127.0.0.1", 8087 
    client.puts "hello" 
    client.gets 
    end 
+0

tadmanの答えのおかげで、問題はバックログが小さすぎることがわかりました。 "crab.listen 100"がTCPServer.newの後に挿入されたときに、問題が再現されました。 – lululau