0

サーバーソケットを使用して、クライアントとサーバー間の接続をセットアップしようとしています。私も使っていませんjava.nio

問題は、常にテスト メッセージを送信し、メッセージの送信に成功したかどうか (クライアントがまだ接続されているかどうか) を検出し、そうでない場合はクライアントが切断されていることです。

ここに示されています:

    try
    {
        Scanner in = new Scanner(socket.getInputStream());
        BufferedReader in_2 = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        while(stopThread)
        {
                if(in_2.ready())
                {
                    String message = in_2.readLine();
                    dt = new DateTime();

                    PrintStream out = new PrintStream(socket.getOutputStream());
                    server.detect(message, dataSets, out);

                    dataSets.add(message);
                    GUI.textArea_1.append(message + "\r\n");
                    GUI.textArea_1.setCaretPosition(GUI.textArea_1.getDocument().getLength());
                }
                else
                {
                    PrintStream out = new PrintStream(socket.getOutputStream());
                    out.println("Testing Connection \r\n");
                    if(out.checkError())
                    {
                        try
                        {
                            socket.close();
                        } 
                        catch (IOException e) 
                        {
                            e.printStackTrace();
                        }
                        stopThread = false;
                        GUI.textArea.append(userName + " disconnected \r\n");
                        GUI.textArea.setCaretPosition(GUI.textArea.getDocument().getLength());
                        server.inputDataForm(userName, dt, dataSets);
                    }
                    Thread.sleep(3000);
                }

        }

問題は、Thread.sleep(3000)が実際にデータの取得を妨げていることです。3 秒後に大量のデータが取得されるためです (スレッドを 3 秒間停止したため)。

さて、私が提案したのは、else ステートメントの無名クラスです。

class runThread implements runnable
{
     void run()
     {
          //Put the else statement here
     }
}

しかし、 stopThread = false は、私が制御しようとしている定数ではありません。

私が検索した他のスレッドは、匿名クラス内の main 内に変数を配置するだけですが、クライアントが切断された場合に while ループを停止するには stopThread が必要です。

誰にもアイデアはありますか?

ありがとう!

4

2 に答える 2

2

ソケットに短いタイムアウトを設定することを検討してください。これにより、ソケットからのデータを待機している間、スレッドがブロックする時間を制御できます。

データがすぐに利用できない場合は、非常に具体的なjava.net.SocketTimeoutException問題が発生します。stopThreadフラグを確認することで、この例外を処理できます。設定されている場合は、メソッドから戻ることができます。それ以外の場合、ソケットは引き続き有効であり、タイムアウトを指定して別の読み取り操作を試すことができます。

他の例外タイプがスローされた場合、ソケットはおそらく無効になっています。

  socket.setSoTimeout(20); /* 1/50th of a second. */
  BufferedReader in = new BufferedReader
    (new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
  while (!stop) {
    try {
      String message = in.readLine();
      if (message == null) 
        handleEOF();
      else
        handleMessage(message);
    } catch(SocketTimeoutException ignore) {
      /* Loop back to check "stop" flag. */
      continue;
    } catch(IOException ex) {
      handleDisconnection();
      break;
    }
  }

ところで、Swing を使用している場合は、Swing のイベント ディスパッチ スレッドからのグラフィカル コンポーネントのみを変更できることに注意してください。また、このソケット処理のような長時間実行される操作で EDT を結び付けることはできません。このスレッドから Swing のinvokeLater()ユーティリティにタスクを渡す必要があります。

于 2013-05-14T00:30:29.247 に答える
1

runnable を実装するだけでなく、メソッド stop(); を持つクラスを作成してみませんか?

public class MyRunner implements Runnable(){
    MutableBoolean stop = false;
    public void run(){...}
    public void stop(){
        stop = true;
    }
}
于 2013-05-13T23:49:16.307 に答える