私は最近、ノンブロッキングソケットを備えたJava NIOベースのサーバーを作成していて、データの書き込みに関していくつかの問題にぶつかりました。ノンブロッキング書き込みがByteBufferの一部またはすべてのバイトの書き込みに失敗する状況があることは、今ではわかっています。
私が現在このようなシナリオを処理する方法は、バッファーを巻き戻すか圧縮して、後で次の選択の反復で再度送信しようとすることです。ただし、これによりパフォーマンスが大幅に低下するため、データを高速に送信することが不可欠です。
私は次のようなものを使用しようとしました:
ByteBuffer bb = ...;
SocketChannel sc = ...;
while(bb.remaining() > 0) {
sc.write(bb);
}
ただし、これに伴う問題は、0バイトを書き込んでも、whileループを終了する可能性があるという事実です。理由はわかりませんが、write()のようです。メソッドは、実際にすべてのバイトを送信したかどうかに関係なく、ByteBufferの制限に達します。
この書き込み方法で私が抱えていたもう1つの問題は、負荷が高い場合に、ブロッキング書き込みを試みていなくても、バッファオーバーフロー例外が発生することがあることです。
ブロッキング書き込みを適切に実行する方法と、SocketChannel.write(ByteBuffer)がバッファをオーバーフローさせる可能性のある条件についてのアドバイスがどうしても必要です(制限に達したときに停止しないでください)。
前もって感謝します。
編集:sc.write(bb)が0バイトを書き込んだとしても、バッファ内の位置をbb.limit()に設定する理由はまだわかりません。私の唯一の手段は、書き込みの試行に失敗した後、バッファを巻き戻すことです。