在异步读取期间TcpClient断开连接

我有一些关于完成tcp连接的问题。

  1. 在使用listener.BeginAcceptTcpClient(ConnectionEstabilishedCallback, null);接受客户端后,客户端使用Tcp连接到我的服务器.BeginAcceptTcpClient listener.BeginAcceptTcpClient(ConnectionEstabilishedCallback, null); ,我开始用networkStream.BeginRead(....)阅读。
    当我等待消息时客户端断开连接会发生什么? (例如,它失去了电力,互联网等)
    我怎么知道它什么时候发生?

  2. 如果成功读取后,我会做一些事情,然后调用networkStream.Close(); client.Close(); networkStream.Close(); client.Close(); 客户会看到什么? 如何“优雅地”终止连接?

  3. 如果我正在等待读取(使用BeginRead),然后(在不同的线程上)关闭相同的流会发生什么?

编辑添加:我确实在客户端和服务器之间发生了乒乓消息。 够了吗? 如果我没有收到ping,请终止我的NetworkStream? 肯定有一些更好的东西。

1-如果客户端因拔下电缆而断开连接,则在下次读取或写入sockets之前,您将无法知道。 还要注意tcpClient.Connected属性值不可靠,它的值取决于上次通信; 所以如果最后一次通信成功,那么它的值是真的,否则它是假的。 有关检查的更多信息,请查看此信息

2-如果关闭网络流和客户端,则这是客户端的正常终止。

3-我不知道,给它一个测试。

如果您因为拔掉电缆而导致连接丢失,那么为了获得适当的IsConnected值,您必须了解在读取或写入tcp期间丢失的连接,因此您需要通过尝试来访问tcpclient成员 – 抓住它的运作….

使用此IsConnected属性检查tcpClient是否已连接:

 public static bool IsConnected { get { try { //return _tcpClient != null && _tcpClient.Client != null && _tcpClient.Client.Connected; if (_tcpClient != null && _tcpClient.Client != null && _tcpClient.Client.Connected) { /* As the documentation: * When passing SelectMode.SelectRead as a parameter to the Poll method it will return * -either- true if Socket.Listen(Int32) has been called and a connection is pending; * -or- true if data is available for reading; * -or- true if the connection has been closed, reset, or terminated; * otherwise, returns false */ // Detect if client disconnected if (_tcpClient.Client.Poll(0, SelectMode.SelectRead)) { byte[] buff = new byte[1]; if (_tcpClient.Client.Receive(buff, SocketFlags.Peek) == 0) { // Client disconnected return false; } else { return true; } } return true; } else { return false; } } catch { return false; } } } 

当我等待消息时客户端断开连接会发生什么? (例如,它失去了电力,互联网等)我怎么知道它何时发生?

不同的断开原因会发生不同的事情。

socket.EndRead收到0个字节时,会检测到正常断开连接。 其他关闭将导致EndReadSend SocketException

如果成功读取后,我会做一些事情,然后调用networkStream.Close(); client.Close(); 客户会看到什么? 如何“优雅地”终止连接?

关闭将优雅地完成。

如果我正在等待读取(使用BeginRead),然后(在不同的线程上)关闭相同的流会发生什么?

你会得到一个例外。 ObjectDisposedException (如果您处置客户端)或IOException

 public class Example { static NetworkStream stream; static TcpClient client; public static void Main(String[] args) String message = String.Empty; //TCP connection Recon: Console.WriteLine("Connecting..."); Int32 port = 3333; try { client = new TcpClient("ip.ip.ip.ip", port); //Try to connect } catch { Console.WriteLine("Problem while connecting!"); Thread.Sleep(10000); //Waiting 10s before reconnect goto Recon; } Console.WriteLine("Connection established!\n"); stream = client.GetStream(); while (true) { //Buffer byte[] received_bytes = new Byte[1024]; message = ""; Console.WriteLine("Waiting to receive message...\n"); Int32 bytes = stream.Read(received_bytes, 0, received_bytes.Length); message = System.Text.Encoding.GetEncoding("iso-8859-1").GetString(received_bytes, 0, bytes); if (bytes == 0) //If connection abort while reading { Console.WriteLine("Connection failed!"); //Recconecting goto Recon; } Console.WriteLine("Received message: " + message); } } }