TcpClient.Connected は true を返しますが、クライアントは接続されていません。代わりに何を使用できますか?
質問
VB.net では、TcpClient を使用してデータ文字列を取得しています。クライアントが接続されているかどうかを確認するために .Connected プロパティを常にチェックしていますが、クライアントが切断した場合でも、これは true を返します。この問題の回避策として何を使用できますか?
これは、現在のコードの簡素化されたバージョンです。
Dim client as TcpClient = Nothing
client = listener.AcceptTcpClient
do while client.connected = true
dim stream as networkStream = client.GetStream()
dim bytes(1024) as byte
dim numCharRead as integer = stream.Read(bytes,0,bytes.length)
dim strRead as string = System.Text.Encoding.ASCII.GetString(bytes,0,i)
loop
クライアントが切断された場合、少なくとも GetStream() 呼び出しで例外がスローされると考えていたのですが、他のアプリを閉じても例外がスローされません...
ありがとう。
編集 Client.Available をポーリングすることが提案されましたが、それは問題を解決しません。クライアントが「実際に」接続されていない場合、available は単に 0 を返します。
重要なのは、接続を開いたままにして、同じソケット接続経由でデータを複数回受信できるようにしようとしているということです。
解決
NetworkStream.Read が 0 を返した場合、接続は閉じられています。 参照:
読み取りに使用できるデータがない場合、NetworkStream.Read メソッドはデータが使用可能になるまでブロックされます。ブロックを回避するには、DataAvailable プロパティを使用して、データが受信ネットワーク バッファーに読み取り用のキューに入れられているかどうかを判断できます。DataAvailable が true を返した場合、読み取り操作はすぐに完了します。読み取り操作では、size パラメータで指定されたバイト数まで、利用可能な限り多くのデータが読み取られます。 リモート ホストが接続をシャットダウンし、利用可能なデータがすべて受信されている場合、Read メソッドはすぐに完了し、ゼロ バイトを返します。
他のヒント
より良い答え:
if (client.Client.Poll(0, SelectMode.SelectRead))
{
byte[] checkConn = new byte[1];
if (client.Client.Receive(checkConn, SocketFlags.Peek) == 0)
{
throw new IOException();
}
}
https://i.stack.imgur.com/Jb0X2.png
リンク=https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.socket.poll?view=netframework-4.0
他のソケットに時々メッセージを送信するタイマーを設定する必要があります。
新しいタイマーコールバックとして薄暗い TC (Ping のアドレス)
Tick = 新しい Threading.Timer(TC、なし、0、30000)
Sub Ping()
Send("Stil here?")
End Sub
client.connected をポーリングする代わりに、NetworkStream のプロパティを使用して、利用可能なデータがないかどうかを確認することはできますか?
とにかく、あるのは、 ONDotnet.com リスナーなどに関する大量の情報が記載された記事。問題を解決するのに役立つはずです...