2010-10-13 68 views
3

嗨,我在我的SERVER应用程序中有一个断开连接按钮单击事件,如下所示。在直流之前,它会通过发送“/ exit”命令来警告其他客户端。之后,它将关闭其连接。正确停止异步TCP应用程序

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.BeginRecieve()方法。我们如何告诉开始接收方法停止其操作,以便我可以正常关闭。

私人无效接受(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); 


    } 

回答

0

您应使用由BeginXXX方法返回的IAsyncResult。 IIRC,你可以处置WaitHandle

0

客户端是否真的需要知道为什么服务器关闭了连接(您好像发送了一条没有任何理由信息的断开连接消息)?看来你只是发送额外的消息给客户端断开连接。

你可以断开所有的客户端,他们将recive一个关闭套接字消息,这将在客户端显示连接关闭。

在附注上,转换recived字符串没有多少意义,将它从字节数组转换为字符串和完成:)。

本人来说我会做的顺序是:
1)设置一个全局布尔,我们不再接受新客户端(即,如果一个新的客户端试图在这个时候连接,我不会接受它)
2)通过客户名单和断开他们
3)关闭他的列表。