0

次の問題で立ち往生しています。リモート エコー サーバーへの接続を作成しました。次のメソッドは、サーバーから受信したバイトを受信するために使用されます。

public byte[] receive() {       
    byte[] resultBuff = new byte[0];
    byte[] buff = new byte[4096];
    try {
        InputStream in = socket.getInputStream();

        int k = -1;

        while((k = in.read(buff, 0, buff.length)) != -1) {
            System.out.println(k);
            byte[] tbuff = new byte[resultBuff.length + k]; // temp buffer size = bytes already read + bytes last read
            System.arraycopy(resultBuff, 0, tbuff, 0, resultBuff.length); // copy previous bytes
            System.arraycopy(buff, 0, tbuff, resultBuff.length, k);  // copy current lot
            resultBuff = tbuff; // call the temp buffer as your result buff
            String test = new String(resultBuff);
            System.out.println(test);
        }
        System.out.println(resultBuff.length + " bytes read.");         

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return resultBuff;

}

サーバーから次の応答を取得できます。

Connection to MSRG Echo server established

問題は、in.read() の 2 回目の実行でループがスタックすることです。これは、サーバーが EOF 情報などを送信していないことが原因であることを理解しています。

次の 2 つの解決策のどちらが正しいのか、どのように実装するのかわかりません。

  1. サーバーからの各メッセージは、 receive() メソッドの新しい実行によって読み取られます。in.read() メソッドがブロックされないようにするにはどうすればよいですか?

  2. receive() メソッド内のループは、アプリケーションが終了するまで維持する必要があります。これは、私の実装が現在 in.read() を間違って使用していることを意味します。これをどのように実装する必要がありますか。

4

1 に答える 1

1

この質問の鍵は、「メッセージ」という言葉の使い方です。TCP にはメッセージはなく、バイト ストリームのみです。メッセージが必要な場合は、それらを自分で実装する必要があります。完全なメッセージが得られるまで一度に 1 バイトずつ読み取り、処理し、すすぎ、繰り返します。BufferedInputStream を使用して、1 バイト読み取りのコストを償却できます。

しかし、エコー サーバーにはメッセージがありません。したがって、読み取りと蓄積の戦略は不適切です。受け取ったものをすぐにエコーします。

于 2013-10-29T22:31:06.993 に答える