2010-10-13 71 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)關閉他的列表。