Stop a Asyncronous TCP Application Properly
Hi i have a disconnect button click event in my SERVER application as follows.Before it dc, it will alert other clients by sending a "/exit" command.After that it will shutdown its connection.
private void stopBu开发者_开发问答tton_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();
}
The problem is that the server is executing Socket.BeginRecieve() method all the time. How do we tell the begin recieve method to stop its operation so that i can close properly.
private 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);
}
You should use the IAsyncResult
returned by the BeginXXX
methods. IIRC, you can dispose of the WaitHandle
.
Does the clients realy need to know why the server closed the connection(You seem to send a disconnect message with no reason information anyways,)? It seems your just sending a extra message to the clients to disconnect them.
You can just disconnect all the clients, and they will recive a close socket message, this will on the client side show the connection being closed.
On a side note, there is no point in converting the recived string so many times, convert it once from byte array to string and your done :).
Personaly the order i would do it is:
1)Set a global bool, that we are no longer accepting new clients ( IE if a new client tries to connect in this time, i would not accept it)
2)Go over the client list an and disconnect them
3)Shut downt he lister.
精彩评论