Alternative to NetworkStream.Read that indicates remote host has closed the connection?

后端 未结 1 1018
时光说笑
时光说笑 2021-02-03 15:06

With regards to handling a TCP/IP connection using the TcpClient class, is there an alternative for checking whether the remote host has closed the connection other

1条回答
  •  北荒
    北荒 (楼主)
    2021-02-03 15:42

    You can use IOControlCode.KeepAliveValues on the TcpClient.Client to guarantee that a keep-alive check is made at least on the specified interval and then check the TcpClient.Client.Connected property.

    An example how to use it:

    struct tcp_keepalive
    {
        public int OnOff;
        public int KeepAliveTime;
        public int KeepAliveInterval;
    
        public unsafe byte[] Buffer
        {
            get
            {
                var buf = new byte[sizeof(tcp_keepalive)];
                fixed(void* p = &this) Marshal.Copy(new IntPtr(p), buf, 0, buf.Length);
                return buf;
            }
        }
    };
    
    static void KeepAliveTest()
    {
        using(var c = new TcpClient())
        {
            c.Connect("www.google.com", 80);
            var s = c.Client;
            var ka = new tcp_keepalive();
            ka.OnOff = 1; // enable
            ka.KeepAliveTime = 1000 * 60; // 60 seconds of inactivity allowed
            ka.KeepAliveInterval = 1000; // 1 second interval on keep-alive checks (default)
            s.IOControl(IOControlCode.KeepAliveValues, ka.Buffer, null);
            var ns = c.GetStream();
            Console.WriteLine("Connected to " + s.RemoteEndPoint);
            while(true)
            {
                SocketError se;
                s.Blocking = false;
                s.Receive(new byte[0], 0, 0, SocketFlags.Peek, out se);
                s.Blocking = true;
                if(!s.Connected)
                {
                    // se==SocketError.ConnectionReset||SocketError.NetworkReset if the connection was closed because of a keep-alive check
                    Console.WriteLine("Socket disconnected: " + se);
                    break;
                }
                // do other stuff
                if(ns.DataAvailable) ns.Read(new byte[100], 0, 100);
                else Thread.Sleep(10);
            }
        }
    }
    

    0 讨论(0)
提交回复
热议问题