服务器异步套接字 - 检测来自客户端的已关闭连接?

时间:2012-03-01 02:08:23

标签: c# sockets connection

我有来自ms网站的以下源代码:http://msdn.microsoft.com/en-us/library/fx6588te.aspx

我正在尝试检测客户端何时关闭连接。

我试过的一种方法是继续向客户端发送数据,直到我遇到异常。我创建了一个新的线程,它在onDataReceive上执行一次,但是我收到错误“无法访问被处置对象”:

m_workerSocket[socket_id].Send(bytes);

但是如果我把它直接放在onDataReceive中就行了。尝试从另一个线程访问套接字时为什么会出现此异常?

然后我找到了第二个解决方案:

static class SocketExtensions
{

    public static bool IsConnected(this Socket socket)
    {
        try
        {
            return !(socket.Poll(1, SelectMode.SelectRead) && socket.Available == 0);
        }
        catch (SocketException) { return false; }
    }
}

我想在一个单独的线程中运行,以检查套接字何时关闭,但我得到相同的错误。如果我尝试从一个线程中执行此操作,我只会收到错误,如果我将两个解决方案放在其中一个函数中,它们就会执行正常。任何想法如何从一个线程运行?

3 个答案:

答案 0 :(得分:1)

如果只有问题是确定客户端何时断开连接: 我在套接字服务器中遇到了同样的问题,最后我决定在断开连接时从任何客户端向服务器发送断开“flag”。

答案 1 :(得分:1)

试试这段代码:

public static void ReadCallback(IAsyncResult ar)
{
    String content = String.Empty;

    // Retrieve the state object and the handler socket from the asynchronous state object.
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    if (handler != null && !handler.Poll(1, SelectMode.SelectRead) && handler.Connected && handler.Available == 0)
    {
        // Read data from the client socket. 
        int bytesRead = handler.EndReceive(ar);
        if (bytesRead > 0)
        {
            // Parsing data received in here..

            // Enabled received for next data
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
        }
    }
    else
    {
        if (handler.Connected)
        {
            // Client are offline will be detected here
            IPEndPoint clientIP = handler.RemoteEndPoint as IPEndPoint;
            MessageBox.Show(String.Format("IP Client: {0}:{1} disconnected", clientIP.Address, clientIP.Port));
        }
        {
            // Server are offline will be detected here
        }
    }
}

答案 2 :(得分:0)

您所需要做的就是正确处理卸载功能,以便客户端检测到客户端异常关闭。 client.connected在服务器端不是很可靠,但这应该会有所帮助。

... IE

protected override void UnloadContent()
    {

        // TODO: Unload any non ContentManager content here            
        if (client != null)
            client.Close(); // I exist so close the connection...

        // I would place a timout on the server side 
        // client.Available as well to drop inactive clients...

        System.Threading.Thread.Sleep(3000); // Force the Client to stay open long enough to communicate a closure...          
    }
相关问题