1

この問題を理解しようとするのは初めてではありませんが、これが最後になることを願っています:

背景:

Java SocketChannel NIOサーバーがノンブロッキング モードで動作しています。

このサーバーには、メッセージを送受信する複数のクライアントがあります。

"keepalive"各クライアントは時々メッセージでサーバーへの接続を維持します。サーバーの主なアイデアは、クライアントが「常に」接続を維持し、「プッシュ」モードでサーバーからメッセージを受信することです。

今私の質問に:

Java NIOread()関数では、read() が -1 を返す場合、その EOS を意味します。

ここで尋ねた質問で、ソケットが現在のストリームを終了し、閉じる必要がないことを意味することに気付きました..

これについてGoogleでもう少し検索すると、接続が反対側で閉じられていることを意味することがわかりました..

  1. 「ストリーム」という言葉は正確には何を意味しますか? クライアントから送信されている現在のメッセージですか?もうメッセージを送信するクライアント側接続の機能ですか?

  2. SocketChannelクライアントが閉じるように言わなかった場合、クライアント側でa が閉じられるのはなぜですか?

  3. read()return -1 とピア I/O エラーによる接続リセットの違いは何ですか?

これは私が読む方法ですSocketChannel

private JSONObject readIncomingData(SocketChannel socketChannel)
        throws JSONException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException {
    JSONObject returnObject = null;
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    Charset charset = Charset.forName("UTF-8");
    String endOfMesesage = "\"}";
    String message = "";
    StringBuilder input = new StringBuilder();      
    boolean continueReading = true;
    while (continueReading && socketChannel.isOpen()) 
    {
        buffer.clear();         
        int bytesRead = socketChannel.read(buffer);             
        if (bytesRead == -1)
        {
            continueReading = false;                    
            continue;
        }
        buffer.flip();
        input.append(charset.decode(buffer));
        message = input.toString();
        if (message.contains(endOfMesesage))
            continueReading = false;
    }       
    if (input.length() > 0 && message.contains(endOfMesesage))
    {
        JSONObject messageJson = new JSONObject(input.toString());
        returnObject = new JSONObject(encrypter.decrypt(messageJson.getString("m")));
    }           
    return returnObject;
}
4

3 に答える 3

1

「ストリーム」という言葉は正確にはどういう意味ですか?クライアントから送信されている現在のメッセージですか?これ以上メッセージを送信するのはクライアント側接続の機能ですか?

ストリームとは、2つの場所の間、通常はクライアントとサーバーの間を流れるデータを意味しますが、事実上、あらゆる種類のデータが流れます。たとえば、ハードディスクからファイルを読み取る場合は、ディスク上のファイルからプログラムに流れるデータを表すFileInputStreamを使用します。これは非常に一般的な概念です。水がデータである川と考えてください。さらに、それは非常に涼しい種類の川であり、水/データの流れを制御することができます。

クライアントがクライアント側でSocketChannelを閉じるように指示しなかった場合、なぜSocketChannelが閉じられるのでしょうか。

これは、クライアントとサーバー間の接続がリセットまたは中断された場合に発生する可能性があります。プログラムは、接続がライブであり、中断されることはないと想定してはなりません。接続はさまざまな理由で中断されます。ネットワークコンポーネントが不安定な場合や、プラグを引っ張っている場合など、元の場所に置いたままにしておくか、ワイヤレスネットワークがダウンしている可能性があります。また、サーバーが接続を閉じる可能性があります。たとえば、サーバープログラムがダウンした場合、バグがある場合、または接続がタイムアウトになった場合などです。開いている接続は限られたリソースであるため、サーバーが長時間アイドル状態になっている場合は、サーバーがそれらを閉じることを決定する可能性があることを常に覚えておいてください。

read()return-1とピアI/ Oエラーによる接続リセットの違いは何ですか?

read()が-1を返す場合、これは単にストリームに現在データがないことを意味します。接続のリセットとは、おそらくより多くのデータがあったが、接続が存在しなくなったため、このデータを読み取ることができなくなったことを意味します。再び川のアノロジーを取り上げます。データは、2つの村をつなぐ川床(接続)を使用して、上流の村(別名サーバービル)から下流の村(別名クライアントビル)に送られるある量の水と考えてください。これで、サーバービルの誰かが大きなレバーを引くと、水(データ)がサーバービルからクライアントビルに流れ落ちます。サーバービルが送りたい水をすべて送った後、レバーを閉じ、川床は再び空になります(そして接続が閉じられると実際に破壊されます)。これは、Clientvilleが-1を取得する場所です。ここで、ブルドーザーが川床を遮り、水の一部がクライアントビルに到達しないことを想像してみてください。これが「接続リセット」の状況です。

お役に立てれば :)

于 2013-01-04T08:31:04.443 に答える
0

「ストリーム」という言葉は正確には何を意味しますか? クライアントから送信されている現在のメッセージですか?

メッセージではなく、バイトのストリームです。これらのバイトを使用してメッセージを作成できますが、ストリームはユーザーがこれを行っていることを認識しておらず、メッセージをサポートしていません。

クライアントが閉じるように言わなかった場合、クライアント側で SocketChannel が閉じられるのはなぜですか?

もう一方の端が閉じている場合は、-1 でのみ閉じることができます。

read() return -1 とピア I/O エラーによる接続リセットの違いは何ですか?

同じ側​​から接続を閉じる、ネットワーク ケーブルを抜いたなどの接続のタイムアウトなど、別の方法で接続を閉じたりドロップしたりすることができます。

ところで:コードを書いた方法は、NIOをブロックするのに適しています。たとえば、メッセージ全体を複数受信した場合、最初のメッセージ以降は破棄されます。ブロッキング IO を使用し、読み取ったものをすべて保持すると、メッセージが破損したりドロップされたりすることはありません。

于 2013-01-04T08:24:09.023 に答える
0
  1. 「ストリーム」という言葉は正確には何を意味しますか? クライアントから送信されている現在のメッセージですか?

これは基本的に、全二重である接続の片側を意味します。TCP はバイト ストリーム プロトコルであり、各方向に 1 つずつ、2 つの独立したバイト ストリームを提供します。

  1. クライアントが閉じるように言わなかった場合、クライアント側で SocketChannel が閉じられるのはなぜですか?

そうではありません。クライアントは接続を閉じました。これがread()-1 を返すということです。

read() return -1 と、ピア I/O エラーによる接続リセットの違いは何ですか?

read()-1 を返すことは、ピアが接続を適切に閉じたことを意味します。「ピアによる接続のリセット」は、何らかのプロトコル エラーを示します。通常は、ピアによって既に閉じられている接続にデータを書き込んだことを示します。

あなたのコードでは、read()-1 が返された場合、チャネルを閉じる必要があります。他に賢明な方法はありません。

于 2013-01-04T08:54:21.033 に答える