TcpClient disconnect during async read

纵饮孤独 提交于 2020-01-01 14:39:12

问题


I have a few questions about finishing a tcp connection.

  1. A client connects to my server using Tcp, after accepting the client with listener.BeginAcceptTcpClient(ConnectionEstabilishedCallback, null);, I start to read with networkStream.BeginRead(....).
    What happens when the client disconnects while I wait for a message? (e.g. it loses power, internet, etc)
    How do I know when it happens?

  2. If after a successful read, I do some stuff, and then call networkStream.Close(); client.Close(); What will the client see? How do I terminate the connection "gracefully"?

  3. What happens if I'm waiting for a read (with BeginRead), and then (on a different thread) close the same stream?

EDIT TO ADD: I do have a ping-pong message going on between the client and server. Is that enough? If I don't receive ping, terminate my NetworkStream? surely there must be something better.


回答1:


1- If the client disconnected due to cable unplugged you will not know till the next read or write to the socket. also note that the tcpClient.Connected property value is not reliable, it's value depending on the last communication; so if the last communication were succeed then it's value is true otherwise it is false. for more information on that check this.

2- If you close the network stream and the client this is the gracefully termination of the client.

3- I don't know, give it a test.

If you aware from connection lost because of a cable unplugged or so, then to get appropriate IsConnected value you have to be aware from the connection lost during the read or write to the tcp, so you need to access the tcpclient members by potting a try-catch around its operation....

Use this IsConnected property to check if the tcpClient is connected:

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;
        }
    }
}



回答2:


What happens when the client disconnects while I wait for a message? (e.g. it loses power, internet, etc) How do I know when it happens?

Different things happens for different disconnect reasons.

A graceful disconnection is detected when you receive 0 bytes from socket.EndRead. Other shutdowns will lead to SocketException for either EndRead or Send

If after a successful read, I do some stuff, and then call networkStream.Close(); client.Close(); What will the client see? How do I terminate the connection "gracefully"?

Close will do it gracefully.

What happens if I'm waiting for a read (with BeginRead), and then (on a different thread) close the same stream?

You'll get an exception. Either ObjectDisposedException (if you dispose the client) or IOException




回答3:


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);
        }
    }
}


来源:https://stackoverflow.com/questions/6452992/tcpclient-disconnect-during-async-read

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!