0

オブジェクトストリームを介して通信する単純なクライアント/サーバーに要約されるかなり複雑なプロジェクトがあります。

2 つの連続した接続では、すべてが問題なく動作します (1 回接続し、動作し、切断し、再度接続し、動作し、切断します)。クライアントは接続し、ビジネスを行い、終了します。サーバーは、IO エラーなしで、オブジェクト出力ストリームとソケットの両方を正常に閉じます。

3 回目の接続を試みると、接続が確立されているように見えます (ServerSocket.accept() メソッドが通過し、ObjectOutputStream が正常に作成されます)。ただし、データは渡されません。inputStream.readUnshared() メソッドは単純にブロックします。

私は次のメモリ予防措置を講じました。

  1. ソケットを閉じるときが来ると、実行中のすべてのスレッドが停止し、すべてのオブジェクトが無効になります。
  2. writeUnshared() メソッドが呼び出されるたびに、ObjectOutputBuffer がフラッシュされてリセットされます。

誰かが同様の問題に遭遇したことがありますか、または誰か提案がありますか? 残念ながら私のプロジェクトはかなり大きいので、コードのコピーには問題があります。

プロジェクトは次のように要約されます。

サーバーメイン

ServerSocket serverSocket = new ServerSocket(port);

while (true) {
    new WorkThread(serverSocket.accept()).start();
}

作業スレッド (サーバー)

public void run() {
    ObjectInputBuffer inputBuffer = new ObjectInputBuffer(new BufferedInputStream(socket.getInputStream()));

    while (running) {
         try {
              Object myObject = inputBuffer.readUnshared();

              // do work is not specified in this sample
              doWork(myObject);
         } catch (IOException e) {   
              running = false;
         }
    }

    try {
         inputBuffer.close();
         socket.close(); 
    } catch (Exception e) {
         System.out.println("Could not close.");
    }
}

クライアント

public Client() {
    Object myObject;
    Socket mySocket = new Socket(address, port);

    try {
         ObjectOutputBuffer output = new ObjectOutputBuffer(new BufferedOutputStream(mySocket.getOutputStream()));

         output.reset();
         output.flush();
    } catch (Exception e) {
         System.out.println("Could not get an input.");
         mySocket.close();
         return;
    }

    // get object data is not specified in this sample. it simply returns a serializable object
    myObject = getObjectData();

    while (myObject != null) {
         try {
              output.writeUnshared(myObject);
              output.reset();
              output.flush();
         } catch (Exception e) {
              e.printStackTrace();
              break;
         } // catch
    } // while

    try {
         output.close();
         socket.close();
    } catch (Exception e) { 
         System.out.println("Could not close.");
    }
}

助けていただけるかもしれないすべての人に感謝します!

4

2 に答える 2

2

(1) ObjectInputBuffer と ObjectOutputBuffer とは? ObjectInputStream と ObjectOutputStream のことですか?

(2) その場合、ObjectOutputStream を作成した直後に reset() を呼び出すのは、時間と帯域幅の無駄です。

(3) 出力ストリームを作成する例外で「入力を取得できませんでした」と出力するのはなぜですか?

(4) 例外が発生した場合は、常にそのメッセージを出力する必要があります。完全に独自のメッセージに置き換えないでください。有益な情報を捨てるだけです。

(5)読み取り時の IOException は、ストリームの終わりを意味すると想定しています。EOFException だけがそれを意味します。その他の IOException は、出力またはログに記録する必要があります。明らかに、ここで他の例外が発生し、それを無視しています。

(6) なぜ同じオブジェクトを送信し続けるのですか?

于 2010-05-22T01:15:31.380 に答える
0

readUnshared() の ObjectInputStream API から:

ObjectInputStream から「非共有」オブジェクトを読み取ります。このメソッドは readObject と同じですが、その後の readObject と readUnshared の呼び出しが、この呼び出しで取得したデシリアライズされたインスタンスへの追加の参照を返さないようにする点が異なります。

これが問題でしょうか?代わりに readObject() を使用してください。

于 2010-05-22T02:08:00.207 に答える