【问题标题】:C# Check if socket is disconnected?C#检查套接字是否断开连接?
【发布时间】:2011-04-18 04:09:02
【问题描述】:

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

【问题讨论】:

    标签: c# events sockets polling


    【解决方案1】:

    创建一个继承.net socket类的cusomt 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 不可靠
    • 自定义类中实现的新 Connected 属性。试试吧,它会工作的。
    • 轮询方法在 linux 上不起作用。即使套接字关闭,它也会继续返回 false。这就是为什么我正在寻找一种不使用 Poll 的方法。
    • 你想在单声道中使用这个方法吗?我已编辑答案以在套接字关闭后停止传播事件。轮询方法在 Windows 中为我工作。我不知道你想在哪里使用它。
    • 它可以在带有单声道的 Windows 上工作,但在带有单声道的 linux 上却不行。
    【解决方案2】:

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

    【讨论】:

    • 除非我自己断开 Socket,否则 Connected 属性似乎总是​​正确的。我刚刚检查了一下,即使远程服务器断开了套接字,它仍然返回 true。
    猜你喜欢
    • 2011-02-09
    • 2010-10-05
    • 2018-05-05
    • 1970-01-01
    • 1970-01-01
    • 2020-07-04
    • 2012-12-10
    • 1970-01-01
    • 2010-12-20
    相关资源
    最近更新 更多