1

SocketServerの最初の接続は、4 つすべての接続が提供される WorkerThread を作成する前に、少なくとも 4 つの接続をリッスンします。 Socketまた、同じスレッドで、接続されたクライアントとの通信を実行するために 4 つのソケットすべてが開かれます。

ここで、サーバーが既に 2 つのソケット接続を受け入れているが、スレッドの作成を続行する前に、残りの 2 つのクライアントをリッスンしている状況を考えてみましょう。

そして、そのリッスン段階の間、接続されたクライアントには「待機中...」というメッセージが表示されます (サーバーはクライアントに応答を返すためのソケットをまだ開いておらず、socket.readObject()クライアント側でブロックしているため)、サーバーが 4 つすべてを取得するまで。一緒に働くクライアント。その間、「既に接続されている」クライアントの 1 つがその「待機中...」を強制終了し、クライアント アプリを閉じます。このような場合、WorkerThread は、ソケットを開こうとすると、提供されたデッド ソケットが原因で例外を発生させます。

ソケットを開かずに (クライアントが失われたため) ソケットが何も指していないかどうかを知るにはどうすればよいですか? (メインスレッドから開くと、実際に使用されるはずのWorkerThreadから再度開くことができないため)。

Socket が死んでいるかどうかがわかれば、サーバーをリッスン状態に戻し、スレッドの作成に進む前に 4 つの接続の取得を試みることができます。

SocketServerは行き詰まることを知っているaccept()ので、上記で尋ねたことを確認できたとしても、すでに「受け入れられた」ソケット接続の活性を監視する別のスレッドを作成する必要があります。

アップデート

つまり、ソケットを開かないということは、以下のようなものです。

Socket s = ss.accept();
/* I'll not be doing as below, since once I close InputStream and OutputStream in main Thread, I can't open in WorkerThread.
But I still want to know if Socket s is connected to client, before I start WorkerThread.


ObjectInputStream in = new ObjectInputStream(s.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
String msg = in.readObject().toString();
System.out.println("Client Says:");
out.writeObject("success");
in.close();
out.close();

*/
new WorkerThread(s).start();

そして、私のサーバーはそのような接続を 4 つ受け入れていることに注意してください。4 つのソケットがaccept()ed の場合、4 つすべてをWorkerThreadのコンストラクターに渡し、別の 4 つのクライアントに戻りaccept()ます。

4

1 に答える 1

1

受け入れをより適切に処理する必要があるだけだと思います。IOExceptionソケットの読み取りまたは書き込みを試みるたびに、 を正しく処理する必要があります。

1 つのオプションは、受け入れコードに「まだ待機中」のメッセージをクライアントに送信させ、他の接続を待機している間に確認応答を頻繁に取得することです。ソケットと関連するストリームは によってすでに作成されているaccept()ため、これを実行して を呼び出し、ハンドラに渡すことができflush()ますOutputStream

ストリームを呼び出さない限りclose()、問題なく再利用できるはずです。ストリームを同時に使用する 2 つの異なるスレッドを持つことはできません。

于 2012-06-14T02:36:49.580 に答える