我在我的SERVER应用程序中有一个断开连接按钮单击事件,如下所示。在它之前,它将通过发送“/ 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.BeginRecieve()方法。我们如何告诉开始接收方法停止其操作,以便我可以正常关闭。
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);
}
答案 0 :(得分:0)
您应该使用IAsyncResult
方法返回的BeginXXX
。 IIRC,您可以处置WaitHandle
。
答案 1 :(得分:0)
客户端是否真的需要知道服务器关闭连接的原因(您似乎发送了一条没有原因信息的断开连接消息)?看来你只是向客户发送一条额外的消息来断开它们。
你可以断开所有客户端的连接,他们会收到一个关闭套接字消息,这将在客户端显示连接被关闭。
另一方面,将转换后的字符串转换多次是没有意义的,将它从字节数组转换为字符串,然后完成:)。
Personaly我会这样做的顺序是:
1)设置一个全局bool,我们不再接受新客户端(IE如果新客户端在此时尝试连接,我不接受它)
2)浏览客户列表并断开连接
3)关闭他的lister。