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

问题描述

| 我对完成TCP连接有一些疑问。 客户端使用Tcp连接到我的服务器,在接受带有“ 0”的客户端后,我开始以“ 1”进行读取。 如果客户端在等待消息时断开连接,会发生什么情况? (例如,它断电,上网等) 我怎么知道什么时候发生? 如果在成功阅读之后,我做了一些工作,然后致电ѭ2client客户会看到什么?如何“优雅地”终止连接? 如果我正在等待读取(使用BeginRead),然后(在另一个线程上)关闭同一流,会发生什么情况? 编辑添加:我确实在客户端和服务器之间有一条乒乓消息。够了吗?如果我没有收到ping命令,是否终止NetworkStream?当然,必须有更好的东西。     

解决方法

        1-如果客户端由于电缆拔出而断开连接,则在下一次读取或写入套接字之前,您将不知道。还请注意,tcpClient.Connected属性值不可靠,该值取决于上一次通信;因此,如果最后一次通信成功,则其值为true,否则为false。有关该信息的更多信息,请检查此。 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个字节时,将检测到正常断开连接。其他关闭将导致
EndRead
Send
变为
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,received_bytes.Length);
            message = System.Text.Encoding.GetEncoding(\"iso-8859-1\").GetString(received_bytes,bytes);

            if (bytes == 0) //If connection abort while reading
            {
                Console.WriteLine(\"Connection failed!\");

                //Recconecting
                goto Recon;
            }

            Console.WriteLine(\"Received message: \" + message);
        }
    }
}