私はちょっと上品な方法で扱うことができないと思っています。いくつかの質問に答えた別の解決策(this、thisなど)を試した後も、ケーブルを抜くことでソケットの切断を検出できませんでした。 。ソケットの切断を検出していますか?
NIOノンブロッキングソケットを使用していますが、サーバーの切断を検出する方法が見つからないことを除いて、すべてが完全に機能します。
私は、次のコードを持っている:SocketChannelsが読み込まれている間、私はケーブルを抜いて、スピンと0を返すSelector.select()
開始、今私はがまたは読み書きする機会を持っていない
while (true) {
handlePendingChanges();
int selectedNum = selector.select(3000);
if (selectedNum > 0) {
SelectionKey key = null;
try {
Iterator<SelectionKey> keyIterator = selector.selelctedKeys().iterator();
while (keyIterator.hasNext()) {
key = keyIterator.next();
if (!key.isValid())
continue;
System.out.println("key state: " + key.isReadable() + ", " + key.isWritable());
if (key.isConnectable()) {
finishConnection(key);
} else if (key.isReadable()) {
onRead(key);
} else if (key.isWritable()) {
onWrite(key);
}
}
} catch (Exception e) {
e.printStackTrace();
System.err.println("I am happy that I can catch some errors.");
} finally {
selector.selectedKeys().clear();
}
}
}
をチャンネルは、&の主な読書コードがif (selectedNum > 0)
によって守られているので、今これはthis answerから、は、チャンネルが壊れて、選択()が返され、選択が返されると言われている最初の混乱です。のキーピア場合
:
select()
はまだEJP's answerから同様の質問には、また0を返し、キーが選択されていない、チャネルは、読み出し/書き込み可能なを示しますが、それはここでは明らかにそうではありません閉じたソケット:
- 読み取りは、()THR)()-1
- のreadLineを(nullを返します
- readXXXを返します。 OWS EOFExceptionでは、他のどのX.
ないのいずれか、ここの場合のために、私は戻りませんそれらのキーからの読み取り、if (selectedNum > 0)
コメントアウトし、それらが選択されているかどうかにかかわらず、すべてのキーを取得するためにselector.keys().iterator()
を使用してみました-1(代わりに0が返されます)、これらのキーへの書き込みにはEOFException
がスローされません。私はただ1つのことを指摘しました。キーが選択されていないとしても、key.isWritable()
が偽を返す間にkey.isReadable()
が真を返します(これは私がOP_WRITEのキーを登録しなかったためかもしれません)。
私の質問は、Javaソケットがこれと同じように動作しているのか、間違っていたのかということです。
OSがまだ接続が壊れていると宣言していない可能性があります。ケーブルを接続し直すと、理論上接続が再開される可能性があります。 – MvG
はい、ケーブルを差し込んだときに接続が再開されることがあります。時には 'select()'を0に戻したままで、手動でキーをキャンセルすることはできません。 – neevek