如何知道什么时候一个Socket已断开 [英] How to tell when a Socket has been disconnected

查看:220
本文介绍了如何知道什么时候一个Socket已断开的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在客户端我需要知道当/如果我的插座连接已经断开。然而Socket.Connected属性始终返回true,即使在服务器端已经断开,我已经试图通过它发送数据。谁能帮我弄清楚是怎么回事。我需要知道什么时候一个套接字已断开连接。

 插座的ServerSocket = NULL;
        的TcpListener监听器=新的TcpListener(1530年);
        listener.Start();
        listener.BeginAcceptSocket(新的AsyncCallback(委托(IAsyncResult的结果)
        {
            的Debug.WriteLine(接受维套接字连接);
            的TcpListener currentListener =(的TcpListener)result.AsyncState;
            ServerSocket的= currentListener.EndAcceptSocket(结果);
        }),监听器);


        插座ClientSocket的=新的Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        的Debug.WriteLine(客户端套接字连接:+ clientSocket.Connected); //应为FALSE,并且它是
        clientSocket.Connect(本地主机,1530年);
        的Debug.WriteLine(客户端套接字连接:+ clientSocket.Connected); //应为TRUE,并且它是

        Thread.sleep代码(1000);
        serverSocket.Close(); //此处关闭服务器套接字
        Thread.sleep代码(1000);

        clientSocket.Send(新的字节[0]); //发送数据应导致插座来更新其Connected属性。
        的Debug.WriteLine(客户端套接字连接:+ clientSocket.Connected); //应该是假的,但其始终为TRUE
 

解决方案

做了一些测试后,似乎对Socket.Connected的文件是错误的,或者至少是误导性的。 clientSocket.Connected 只会成为继 clientSocket.close假()被调用。我认为这是一个倒退到原来的C Berkeley套接字API和它的术语。套接字被绑定时,它具有与之相关联的本地地址,以及一个插座连接时,它具有与之相关联的远程地址。即使远程方已关闭了连接,本地套接字仍然有关联,因此它仍是连接。

不过,这里有一个方法,它的确实的工作:

 (socket.Poll(0,SelectMode.SelectRead)及和放大器; socket.Available == 0)!
 

它依赖于这一事实,即使没有数据可用在关闭的连接将被标记为可读。

如果要检测,如突然被关闭断网络线缆或计算机的条件下,情况比较复杂一点。在这些条件下,您的计算机永远不会收到一个数据包,表明套接字已关闭。它需要检测远端已经消失发送数据包,并注意到一点反应都没有回来。您可以在应用程序级别这样做,因为你的协议的一部分,也可以使用TCP keepalive选项。使用TCP保持活动从.NET是特别不容易;你可能会更好过建立一个保活机制到您的协议(或者,你可以要求一个独立的问题:我如何启用TCP保活在.NET和设置保活间隔?)。

On the client side I need to know when/if my socket connection has been broken. However the Socket.Connected property always returns true, even after the server side has been disconnected and I've tried sending data through it. Can anyone help me figure out what's going on here. I need to know when a socket has been disconnected.

        Socket serverSocket = null;
        TcpListener listener = new TcpListener(1530);
        listener.Start();
        listener.BeginAcceptSocket(new AsyncCallback(delegate(IAsyncResult result)
        {
            Debug.WriteLine("ACCEPTING SOCKET CONNECTION");
            TcpListener currentListener = (TcpListener)result.AsyncState;
            serverSocket = currentListener.EndAcceptSocket(result);
        }), listener);


        Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        Debug.WriteLine("client socket connected: " + clientSocket.Connected);//should be FALSE, and it is
        clientSocket.Connect("localhost", 1530);
        Debug.WriteLine("client socket connected: " + clientSocket.Connected);//should be TRUE, and it is

        Thread.Sleep(1000);
        serverSocket.Close();//closing the server socket here
        Thread.Sleep(1000);

        clientSocket.Send(new byte[0]);//sending data should cause the socket to update its Connected property.
        Debug.WriteLine("client socket connected: " + clientSocket.Connected);//should be FALSE, but its always TRUE

解决方案

After doing some testing, it appears that the documentation for Socket.Connected is wrong, or at least misleading. clientSocket.Connected will only become false after clientSocket.close() is called. I think this is a throwback to the original C Berkeley sockets API and its terminology. A socket is bound when it has a local address associated with it, and a socket is connected when it has a remote address associated with it. Even though the remote side has closed the connection, the local socket still has the association and so it is still "connected".

However, here is a method that does work:

!(socket.Poll(0, SelectMode.SelectRead) && socket.Available == 0)

It relies on that fact that a closed connection will be marked as readable even though no data is available.

If you want to detect conditions such as broken network cables or computers abruptly being turned off, the situation is a bit more complex. Under those conditions, your computer never receives a packet indicating that the socket has closed. It needs to detect that the remote side has vanished by sending packets and noticing that no response comes back. You can do this at the application level as part of your protocol, or you can use the TCP KeepAlive option. Using TCP Keep Alive from .NET isn't particularly easy; you're probably better off building a keep-alive mechanism into your protocol (alternately, you could ask a separate question for "How do I enable TCP Keep Alive in .NET and set the keep alive interval?").

这篇关于如何知道什么时候一个Socket已断开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆