How to check if a socket is connected/disconnected in C#?

前端 未结 11 1231
礼貌的吻别
礼貌的吻别 2020-11-28 18:50

How can you check if a network socket (System.Net.Sockets.Socket) is still connected if the other host doesn\'t send you a packet when it disconnects (e.g. because it discon

11条回答
  •  误落风尘
    2020-11-28 19:08

    public static class SocketExtensions
    {
        private const int BytesPerLong = 4; // 32 / 8
        private const int BitsPerByte = 8;
    
        public static bool IsConnected(this Socket socket)
        {
            try
            {
                return !(socket.Poll(1000, SelectMode.SelectRead) && socket.Available == 0);
            }
            catch (SocketException)
            {
                return false;
            }
        }
    
    
        /// 
        /// Sets the keep-alive interval for the socket.
        /// 
        /// The socket.
        /// Time between two keep alive "pings".
        /// Time between two keep alive "pings" when first one fails.
        /// If the keep alive infos were succefully modified.
        public static bool SetKeepAlive(this Socket socket, ulong time, ulong interval)
        {
            try
            {
                // Array to hold input values.
                var input = new[]
                {
                    (time == 0 || interval == 0) ? 0UL : 1UL, // on or off
                    time,
                    interval
                };
    
                // Pack input into byte struct.
                byte[] inValue = new byte[3 * BytesPerLong];
                for (int i = 0; i < input.Length; i++)
                {
                    inValue[i * BytesPerLong + 3] = (byte)(input[i] >> ((BytesPerLong - 1) * BitsPerByte) & 0xff);
                    inValue[i * BytesPerLong + 2] = (byte)(input[i] >> ((BytesPerLong - 2) * BitsPerByte) & 0xff);
                    inValue[i * BytesPerLong + 1] = (byte)(input[i] >> ((BytesPerLong - 3) * BitsPerByte) & 0xff);
                    inValue[i * BytesPerLong + 0] = (byte)(input[i] >> ((BytesPerLong - 4) * BitsPerByte) & 0xff);
                }
    
                // Create bytestruct for result (bytes pending on server socket).
                byte[] outValue = BitConverter.GetBytes(0);
    
                // Write SIO_VALS to Socket IOControl.
                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
                socket.IOControl(IOControlCode.KeepAliveValues, inValue, outValue);
            }
            catch (SocketException)
            {
                return false;
            }
    
            return true;
        }
    }
    
    1. Copy the SocketExtensions class to your project
    2. Call the SetKeepAlive on your socket - socket.SetKeepAlive(1000, 2);
    3. Add a timer to check the IsConnected function

提交回复
热议问题