【问题标题】:Server Async Sockets - Detect closed connection from client?服务器异步套接字 - 检测来自客户端的关闭连接?
【发布时间】:2016-11-11 18:32:05
【问题描述】:

我有以下来自 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; }
    }
}

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

【问题讨论】:

  • 检测套接字断开的唯一可靠方法是尝试从连接中读取,而不是写入。
  • 谢谢!我一直收到同样的错误,任何提示我做错了什么!?!

标签: c# sockets connection


【解决方案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
        }
    }
}

【讨论】:

  • 在条件下 if (handler! = null &&! handler.Poll (1, SelectMode.SelectRead) && handler.Connected && handler.Available == 0) 我会交换订单 if (handler! = null && handler.Connected &&! handler.Poll(1, SelectMode.SelectRead) ... 否则,当socket未连接时,Poll函数以异常结束。
【解决方案2】:

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

【讨论】:

  • 谢谢,我已经尝试过断开连接标志,但不幸的是它对我不起作用。我只需要检测何时关闭连接。
【解决方案3】:

您所要做的就是正确处理您的卸载功能,以便您的客户端检测到客户端异常关闭。 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...          
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 2020-01-31
    • 1970-01-01
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多