正确停止异步TCP应用程序

3

你好,我有一个在服务器应用程序中的断开按钮点击事件,代码如下。在执行断开操作之前,它会通过发送“/exit”命令来通知其他客户端。然后关闭它的连接。

 private void stopButton_Click(object sender, EventArgs e)
    {
        byte[] exit_command = Encoding.ASCII.GetBytes("/exit");
        g_server_conn.BeginSend(exit_command, 0, exit_command.Length, SocketFlags.None, new AsyncCallback(Send), g_server_conn);
        g_server_conn.Shutdown(SocketShutdown.Both);
        g_server_conn.Close();
    }

问题在于服务器一直在执行Socket.BeginReceive()方法。我们该如何告诉BeginReceive方法停止操作,以便我可以正确地关闭它。
私有void Accept(IAsyncResult iar) {
        Socket winsock = (Socket)iar.AsyncState;
        g_server_conn = winsock.EndAccept(iar);


        //Function that exchanges names of each other
        NewClient(g_server_conn);

        Socket server_conn = g_server_conn;

        chat_msg = new byte[1024];
        server_conn.BeginReceive(chat_msg, 0, chat_msg.Length, SocketFlags.None, new AsyncCallback(Recieve), server_conn);

    }

    private void Recieve(IAsyncResult iar)
    {
        Socket server_conn = (Socket)iar.AsyncState;
        server_conn.EndReceive(iar);

        //If clients shutdown connection,Server recieves /exit command
        if (Encoding.ASCII.GetString(chat_msg, 0, chat_msg.Length) == "/exit")
        {
            g_server_conn.Shutdown(SocketShutdown.Both);
            g_server_conn.Close();
            return;
        }
        SetLabel(client_name, chatListBox);
        SetLabel(Encoding.ASCII.GetString(chat_msg), chatListBox);

        chat_msg = new byte[1024];
        server_conn.BeginReceive(chat_msg, 0, chat_msg.Length, SocketFlags.None, new AsyncCallback(Recieve), server_conn);


    }
2个回答

0

你应该使用由BeginXXX方法返回的IAsyncResult。如果我没记错,你可以处理WaitHandle


0

客户端真的需要知道服务器为什么关闭连接吗(无论如何,您似乎发送了一个没有原因信息的断开消息)?看起来您只是向客户端发送了一个额外的消息来断开它们。

您可以直接断开所有客户端,他们将收到一个关闭套接字消息,这将在客户端上显示连接已关闭。

顺便说一句,没有必要多次转换接收到的字符串,只需将其从字节数组转换为字符串即可 :)。

个人认为我会按以下顺序进行:
1)设置全局布尔值,表示我们不再接受新客户端(即如果在此期间尝试连接新客户端,则不会接受)
2)遍历客户端列表并断开连接
3)关闭监听器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接