プロジェクト用のコアNIOサーバーのネットワークコードを書き直しています。将来の使用のために接続情報をいつ保存するべきかを把握しようとしています。たとえば、クライアントが通常の方法で接続すると、そのクライアントにSocketChannelオブジェクトを格納して関連付けて、いつでもそのクライアントにデータを書き込むことができます。一般的には、クライアントのIPアドレス(ポートを含む)をSocketChannelオブジェクトにマップするHashMapのキーとして使用します。そうすれば、私は自分のIPアドレスを簡単に検索し、そのSocketChannel経由で非同期にデータを送信することができます。Java NIO:OP_ACCEPTとOP_READの関係?
これは最善の方法ではないかもしれませんが、プロジェクトは大きすぎて基本的なネットワークコードを変更することはできませんが、私は提案を検討します。しかし、私の主な質問は次のとおりです。
将来の使用のためにSocketChannelをどのような場所に保存する必要がありますか?私は、接続が受け入れられると(OP_ACCEPTを介して)SocketChannelへの参照を格納しています。 OP_READイベントが発生したときにマップエントリがすでに存在していると仮定できるため、これは効率的なアプローチです。そうでなければ、OP_READが発生するたびに計算上高価なHashMapのチェックを行う必要があります。 OP_ACCEPTより多くのものがクライアントのために発生します。私の恐れは、受け入れられる(OP_ACCEPT)いくつかの接続がありますが、決してデータを送信しない(OP_READ)ことがあります。おそらく、これはファイアウォールの問題やクライアントまたはネットワークアダプタの機能不全のために可能です。これはアクティブではないが、クローズメッセージを受け取ることのない「ゾンビ」接続につながる可能性があると私は思う。
私のネットワークコードを書き直す私の理由の一部は、まれには、私は奇妙な状態になっているクライアント接続を取得することです。私はOP_ACCEPT対OP_READを処理した方法を考えています。接続を「有効」と仮定して格納することができ、間違っている可能性があるという情報も含まれます。
私の質問はより具体的ではありません。SocketChannelが本当に有効かどうかを判断する最も効率的な方法を探しています。助けてくれてありがとう!
うわ、大量のためのおかげで(及び品質)の助け!私は今できる限りこの資料を研究しています。 - SelectionKey.register()ではなく、SocketChannel.register()を意味すると思いますか? - NIO用のスレッドを1つだけ使用することで、スレッドの問題のいくつかを回避できますか? - TIME_WAITステータスのソケットを定期的にチェックして、終了する必要がある候補は妥当と思われますか? (あなたが言及した半閉じた問題) ありがとうトン! – DivideByHero
1)はい、register()はSelectableChannel(SocketChannelが拡張)にあります。それが私の意図だった。 2)選択にスレッドを1つだけ使用してから、チャネルを読み取り/書き込みアクションのためにオフにできます。同時接続数が多い場合は、1つのスレッドだけで処理できないことがわかります。それは難しいハンドオフです。 3)定期的にハーフクローズドソケットを探しています。 – mtnygard