C# 如何检查 socket 是否已断开连接?

6
如何在不使用Poll的情况下检查非阻塞套接字是否断开连接?
2个回答

5
创建一个继承 .net socket 类的自定义 socket 类:
public delegate void SocketEventHandler(Socket socket);
    public class CustomSocket : Socket
    {
        private readonly Timer timer;
        private const int INTERVAL = 1000;

        public CustomSocket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType)
            : base(addressFamily, socketType, protocolType)
        {
            timer = new Timer { Interval = INTERVAL };
            timer.Tick += TimerTick;
        }

        public CustomSocket(SocketInformation socketInformation)
            : base(socketInformation)
        {
            timer = new Timer { Interval = INTERVAL };
            timer.Tick += TimerTick;
        }

        private readonly List<SocketEventHandler> onCloseHandlers = new List<SocketEventHandler>();
        public event SocketEventHandler SocketClosed
        {
            add { onCloseHandlers.Add(value); }
            remove { onCloseHandlers.Remove(value); }
        }

        public bool EventsEnabled
        {
            set
            {
                if(value)
                    timer.Start();
                else
                    timer.Stop();
            }
        }

        private void TimerTick(object sender, EventArgs e)
        {
            if (!Connected)
            {
                foreach (var socketEventHandler in onCloseHandlers)
                    socketEventHandler.Invoke(this);
                EventsEnabled = false;
            }
        }

        // Hiding base connected property
        public new bool Connected
        {
           get
           {
              bool part1 = Poll(1000, SelectMode.SelectRead);
              bool part2 = (Available == 0);
              if (part1 & part2)
                 return false;
              else
                 return true;
           }
        }
    }

然后像这样使用它:
        var socket = new CustomSocket(
                //parameters
                );

        socket.SocketClosed += socket_SocketClosed;
        socket.EventsEnabled = true;


        void socket_SocketClosed(Socket socket)
        {
            // do what you want
        }

我刚刚在每个套接字中实现了一个套接字关闭事件。因此,您的应用程序应该为此事件注册事件处理程序。然后,套接字会通知您的应用程序它是否自己关闭 ;)
如果代码有任何问题,请告诉我。

Socket.Connected 不可靠 - Will
自定义类中实现了新的Connected属性。试一下,它会起作用的。 - Farzin Zaker
Poll方法在Linux上不起作用。即使套接字关闭,它仍将继续返回false。这就是为什么我正在寻找一种不使用Poll的方法。 - Will
它在Windows上使用Mono可以工作,但在Linux上使用Mono却不行。 - Will
Linux中的Mono不完整,无法完成此操作。您是正确的。 - Farzin Zaker
显示剩余2条评论

0

Socket类有一个Connected属性。根据MSDN的说明,检查调用是非阻塞的。这不是你要找的吗?


Connected属性似乎总是为true,除非我自己断开Socket连接。我刚刚检查了一下,即使远程服务器已经断开了socket连接,它仍然返回true。 - Will

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接