繁体   English   中英

连接了多个客户端的异步套接字服务器

[英]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);
}

如果您不熟悉服务器和套接字连接,则大致是事件流:

  1. 服务器创建一个侦听器,该侦听器将处理传入的连接并提供回调

  2. 在侦听器上调用BeginAccept以指示服务器已准备好处理连接

  3. 当客户端连接时,侦听套接字会回调:

    3a。 在侦听器套接字上调用EndAccept提供了另一个套接字,在此发生实际的通信。

    3b。 要开始通信,请在通信套接字上调用BeginReceive,并提供一个回调,该回调将接收来自客户端的消息

    3c。 再次调用BeginAccept表示您准备好接收新连接

  4. 收到消息后,通信套接字将回叫:

    4a。 调用EndReceive以读取字节。 如果字节数为0,则另一端正在断开连接

    4b。 处理消息并调用BeginReceive以接收下一条消息

  5. 当您要关闭连接时,发送Shutdown(Send),然后等待另一端通过关闭响应(在BeginReceive回调中将其显示为0字节),然后关闭连接。

这只是一个粗略的概述,但是还有很多很多事情要做。 特别是异常处理可能非常棘手!

为了使整个内容更具可读性,我首先将客户端和服务器部分划分为单独的类-否则所有的send和read方法很快就会变得难以区分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM