[英]Async socket server with multiple clients connected
我想用C#编写一个异步套接字服务器和客户端。 服务器必须管理许多客户端连接,并使其保持活动状态。 我尝试从此站点使用MSDN服务器代码,但是它无法同时处理多个客户端,并且在发送确认消息后关闭连接。 您能告诉我如何更改该示例代码以管理同时向多个客户端发送消息(例如,将客户端连接置于某个数组或列表中)并使连接保持活动状态吗?
请注意,编写异步服务器要比重写MSDN示例花费更多的工作(我目前正在编写处理4-5000个同时连接的异步服务器,这不是一件容易的事!)。
话虽如此,该样本似乎完全能够处理多个客户。 但是,只要您不管理连接,就无法向客户端发送任何消息,也无法以正常的方式关闭服务器(在关闭之前断开所有客户端的连接)。
如果只需要向所有客户端广播消息,则可以轻松列出所有连接的套接字。 即在AcceptCallback中,您应该将处理程序保存在列表中。 为了保持连接打开,请删除SendCallback中的handler.Shutdown()和handler.Close()。 像这样:
private List<Socket> _clients = new List<Socket>();
public static void AcceptCallback(IAsyncResult ar) {
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
_clients.Add(handler); // Maintain connected clients
}
public void BroadcastMessage(string message)
{
// Send the message to all clients
var bytes = Encoding.ASCII.GetBytes(message);
foreach(var c in _clients)
{
c.BeginSend(bytes, 0, bytes.Length, SocketFlags.Broadcast, OnMessageBroadcast, c);
}
}
private void OnMessageBroadcast(IAsyncResult res)
{
Socket client = (Socket)res.AsyncState;
client.EndSend(res);
}
如果您不熟悉服务器和套接字连接,则大致是事件流:
服务器创建一个侦听器,该侦听器将处理传入的连接并提供回调
在侦听器上调用BeginAccept以指示服务器已准备好处理连接
当客户端连接时,侦听套接字会回调:
3a。 在侦听器套接字上调用EndAccept提供了另一个套接字,在此发生实际的通信。
3b。 要开始通信,请在通信套接字上调用BeginReceive,并提供一个回调,该回调将接收来自客户端的消息
3c。 再次调用BeginAccept表示您准备好接收新连接
收到消息后,通信套接字将回叫:
4a。 调用EndReceive以读取字节。 如果字节数为0,则另一端正在断开连接
4b。 处理消息并调用BeginReceive以接收下一条消息
当您要关闭连接时,发送Shutdown(Send),然后等待另一端通过关闭响应(在BeginReceive回调中将其显示为0字节),然后关闭连接。
这只是一个粗略的概述,但是还有很多很多事情要做。 特别是异常处理可能非常棘手!
为了使整个内容更具可读性,我首先将客户端和服务器部分划分为单独的类-否则所有的send和read方法很快就会变得难以区分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.