2011-07-10 10 views
1

私はサーバとクライアントアプリケーションを持っています。現在実装されている方法は次のとおりです。サーバはTcpListenerを介して新しい接続をリッスンするループをスレッド内に持っています。誰かが接続すると、TcpClientをそのTcpClientを特にリッスンするループに渡し、NetworkStreamを介してそのユーザーとのすべての対話を処理します。マルチスレッド+ソケットアプリケーションの適切な実装

クライアントでは、サーバーに接続するTcpClientがあります。どのIOでもブロックモードにするので、それを別のスレッドに分岐する必要があると私は理解しており、メインスレッドを停止させることはできません。

これまでのところ、正しく理解していますか?いずれかのプログラムのメインスレッドを停止することなく、非同期通信を確実に行うためのより簡単な方法はありますか?

いずれにしても、私の主な質問は:これらのスレッドとソケットがすべて正しく処分されていることを確認するにはどうすればよいですか?プログラムがまだブロッキングモードで終了している場合、プログラムはフリーズしているようです。だから私はソケット上のすべてのIOを中止し、完了した子スレッドの無限ループを教えてください。

これはUnity3dプロジェクトでもあります。

答えて

3

独自のスレッドへの新しい接続を引き渡すと、スケーラビリティが低下する可能性があります。また、クライアントのI/Oにスレッド・ハンドオフが必要な理由もありません。

両方の問題を非同期I/Oを使用して解決できます。クライアント上のBeginConnect/EndConnect、読み取りと書き込みのためのサーバー側のBeginRead/EndRead, BeginWrite/EndWrite

あなた自身の新しいスレッドを必要とせずにすべてをイベ​​ント駆動することができます。接続の補完が最初に非同期で読み込まれた後、各読み込みの完了によってそのソケットに新しい非同期読み込み呼び出しがポストされます。書き込みは常にあなたのPOVから決定的です。

ソケットを閉じると、エラーで終了する読み込み/書き込みが保留され、プロセスを完全に終了できるようになります。ソケットが閉じられた後にソケットが使用されないように、適切なロックを実装するように注意してください(おそらくlock()が必要です)。

+0

あなたは私に研究をたくさん与えました!ありがとう、私はおそらく非常に非実用的な何かをやっていると思った。 – Dan

1

TcpListenerと、TcpClientの2つの独立したスレッドが必要です。新しいスレッドを初期化するときにはIsBackgroundプロパティをtrueにして、アプリケーションが終了すると終了するようにします。あなたは、スレッドの代わりに4.0またはThreadPool.QueueUserWorkItemを使用している場合

Thread listenerThread = new Thread(ListenerLoop); 
listenerThread.IsBackground = true; 
listernerThread.Start(); 

あなたはTaskを使用することができます。

+0

N + 1スレッドを意味しませんか?リスナー用に1つ、クライアントごとに1つ – EJP

+0

@EJP:はい、各tcpClientに1つ。 –

関連する問題