基本的に、TcpClient.Connectionを使用しているプロパティは、思ったとおりに機能しません。MSDNドキュメントから:
http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.connected.aspx
Connectedプロパティは最新の操作の時点での接続の状態のみを反映するため、現在の状態を判別するためにメッセージの送受信を試みる必要があります。メッセージの送信が失敗すると、このプロパティはtrueを返しなくなります。この動作は仕様によるものであることに注意してください。テストから送受信までの間に接続が失われた可能性があるため、接続の状態を確実にテストすることはできません。
要点は、ホストが切断された後、サーバーがストリームから別の行を読み取るのを待機するのをブロックする前に、プロパティTcpClient.Connectionが更新されなかったことです。ブロックする前に、接続がアクティブかどうかを検出するためのより信頼性の高い方法が必要です。
結局のところ、この質問は以前に尋ねられたことがあります。そこで、ここから答えを借りて、OPで使用している形式に適合させました。
https://stackoverflow.com/a/8631090
static void Main(string[] args)
{
TcpClient client = new TcpClient();
TcpListener listener = new TcpListener(IPAddress.Loopback, 60123);
listener.Start();
while (true)
{
Console.WriteLine("Waiting for connection...");
client = listener.AcceptTcpClient();
Console.WriteLine("Connection found");
StreamReader reader = new StreamReader(client.GetStream());
string line = string.Empty;
while (TestConnection(client))
{
line = reader.ReadLine();
Console.WriteLine(line);
}
Console.WriteLine("Disconnected");
}
}
private static bool TestConnection(TcpClient client)
{
bool sConnected = true;
if (client.Client.Poll(0, SelectMode.SelectRead))
{
if (!client.Connected) sConnected = false;
else
{
byte[] b = new byte[1];
try
{
if (client.Client.Receive(b, SocketFlags.Peek) == 0)
{
// Client disconnected
sConnected = false;
}
}
catch { sConnected = false; }
}
}
return sConnected;
}
これは私がテストしたときに機能します。機能する理由は、接続を読み書きしようとするまで、接続が閉じているかどうかがわからないためです。これを行うには、盲目的に読み取り/書き込みを試みてから、ソケットが閉じられたときに発生するIO例外を処理します。または、このテスターメソッドが実行していることを実行して、接続が閉じられているかどうかを確認します。
これがお役に立てば幸いです
編集:
これが接続が閉じているかどうかを確認する最も効率的な方法である場合とそうでない場合があることに注意してください。ただし、TcpClientに依存するのではなく、読み取り/書き込みによってサーバー側で接続を自分で確認する必要があることを示しています。繋がり。
編集2:
私のサンプルは古いリソースをうまくクリーンアップしていません。OCD反応を起こした人にはお詫びします。