如何关闭与服务器的所有连接?

时间:2016-04-24 16:54:44

标签: c# sockets

我有一个接受/恢复的服务器并异步发送到客户端连接 我正在使用Tcp。

接受后,所有连接都会保存到列表中:

    List<Socket> clientConnections = new List<Socket>();

如何优雅地断开所有客户端?
请注意我不是要检测客户端断开连接。相反,我想强迫客户断开连接。

我的代码结构:

class ServerListener
{
    List<Socket> clientConnections = new List<Socket>();
    Socket ServerSocket;

    public ServerListener(IPAddress IP, int Port)
    {
        ServerSocket = new Socket(IP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

        ServerSocket.Bind(new IPEndPoint(IP, Port));

        ServerSocket.Listen(10);
        Program.mainForm.changeStatus(frmServer.status.online);
        Program.mainForm.displayIP(((IPEndPoint)ServerSocket.LocalEndPoint).Address.ToString());
        try
        {
            ServerSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);
        }
        catch (Exception)
        {
        }
    }

    void AcceptCallBack(IAsyncResult AR)
    {
        try
        {
            Socket client = ServerSocket.EndAccept(AR);
            clientConnections.Add(client);
            client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallback), client);
            ServerSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);

        }
        catch (Exception)
        {
        }
    }

    void RecieveCallback(IAsyncResult AR)
    {
        Socket client = (Socket)AR.AsyncState;
        int len = client.EndReceive(AR);
        byte[] tempBuffer = new byte[len];

        Array.Copy(buffer, tempBuffer, len);
        string request = Encoding.ASCII.GetString(tempBuffer);

        try
        {
            byte[] sendBuffer = HandleRequest(request);
            client.BeginSend(sendBuffer, 0, sendBuffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), client); // send data
        }
        catch (Exception)
        {
            client.Close();
            clientConnections.Remove(client);
            DisplayClientRequestInfo("User Disconnected.");
        }
    }

    void SendCallback(IAsyncResult AR)
    {
        Socket client = (Socket)AR.AsyncState;
        client.EndSend(AR);

        client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallback), client);
    }

    // listening for changes
    public delegate void textRecievedEventHandler(object sender, EventArgs e, string message);
    public event textRecievedEventHandler messageChanged;

    protected virtual void DisplayClientRequestInfo(string message)
    {
        if (messageChanged != null)
        {
            messageChanged(this, EventArgs.Empty, message);
        }
    }

    // handling requests

    byte[] HandleRequest(string request)
    {
        string response = string.Empty;
        // Create the response...

        return Encoding.ASCII.GetBytes(response);
    }

    public void Stop()
    {
        try
        {
             // disconnect Here

            ServerSocket.Dispose();

            foreach (Socket s in clientConnections)
            {
                KickUser(s);
            }   
        }
        catch (SocketException)
        {

        }
        catch (Exception e)
        {
            DisplayClientRequestInfo(e.Message);
        }
    }

    void KickUser(Socket socket)
    {
        socket.Shutdown(SocketShutdown.Both);
        socket.Close();
    }
}

因此,当用户单击“停止服务器”按钮时,它将运行:

sl.Stop();

其中sl是ServerListener的一个实例。

连接客户端并停止服务器时,出现以下错误:
System.dll

中发生了未处理的“System.ObjectDisposedException”类型异常

其他信息:无法访问已处置的对象。

我认为这是因为连接异步。同样在客户端,socket.Connectedtrue。意思是它仍然认为它连接到服务器。

那么从服务器安全地踢用户的正确方法是什么?

0 个答案:

没有答案