Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 连接了多个客户端的异步套接字服务器_C#_Sockets_Asyncsocket - Fatal编程技术网

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

C# 连接了多个客户端的异步套接字服务器,c#,sockets,asyncsocket,C#,Sockets,Asyncsocket,我想用C编写一个异步套接字服务器和客户端。服务器必须管理许多客户端连接,并尽可能长时间保持它们的活动状态。 我尝试使用MSDN服务器代码,但它无法同时处理多个客户端,并在发送确认消息后关闭连接。您能告诉我如何更改示例代码以管理同时向多个客户端发送消息吗,在某个数组或列表中建立客户端连接并保持连接的活动状态?请注意,编写异步服务器比重写MSDN示例需要更多的工作。我目前正在编写一个异步服务器来处理4-5000个模拟连接,这不是一项简单的任务 这就是说,样本似乎完全能够处理多个客户;但是,只要不管理

我想用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以接收下一条消息

当您想要关闭连接时,发送一个ShutdownSend,并等待另一方回复关机,将在BeginReceive回调中显示为0字节,然后关闭连接

这只是一个粗略的轮廓,但还有很多很多事情需要解决。特别是异常处理可能非常棘手


为了使整个过程更具可读性,我首先将客户机和服务器部分划分为不同的类,否则所有的发送和读取方法很快就无法区分。

我认为这不是一个坏问题,但问题是它太开放了;这是一个巨大的主题,并且没有魔术棒可以让编写一个完全异步的多客户机服务器变得容易。您关于保持连接活动的问题很大程度上取决于协议,因为真正做到这一点的唯一方法是偶尔发送某种消息,即使这样,套接字仍可能因任何原因终止,但至少您会检测到它,最晚在下一个示例中,我有一个web socket rfc6455 etc服务器,它完成了您所描述的一切:它太复杂了,无法用一个stackoverflow问题来描述。好吧,假设我每半秒钟发送一次消息。我只是想知道,如何按照msdn站点上给出的方式连接到带有客户端的服务器,并向已连接的客户端发送消息,因为msdn的解决方案在消息发送后不久关闭连接。我想这就是我目前所需要的。非常感谢:foreach循环的广播不是一个瓶颈吗?我的意思是如果有5000个客户端连接,你必须等待5000个周期?