0

我需要广播连接到服务器的客户端,使用TcpClient. 目前,我有一个 for 遍历整个客户列表,他们会一一收到消息。但是消息之间有一段时间,所以客户端不会同时收到消息。我认为使用多线程或协同程序有效,有人可以建议我吗?我附上广播的功能码

谢谢你们

public void broadCast(string sendMsg)
{
    foreach (User user in clientList)
    {
        if (user.tcpClient != null)
        {
            m_NetStream = user.tcpClient.GetStream();

            if (m_NetStream != null)
            {
                byte[] msgOut = Encoding.ASCII.GetBytes(sendMsg);
                m_NetStream.Write(msgOut, 0, msgOut.Length);
            }
            else
            {
                ServerLog("Socket Error: Start at least one client first", Color.red);
                return;
            }
        }
    }
}
4

1 回答 1

1

如果您想同时发送给多个客户端,我建议Async使用Write. 正如评论中所建议的那样,我还建议创建缓冲区以将其发送出循环。

目前broadCast,在发送所有消息之前,您不会返回,我在下面将其实现为 a ,但如果更合适WaitAll,可以跳过此方法或使用此方法。async

public void broadCast(string sendMsg)
{
    var pendingSends = new List<Task>();
    byte[] msgOut = Encoding.ASCII.GetBytes(sendMsg);
    foreach (User user in clientList)
    {
        if (user.tcpClient != null)
        {
            m_NetStream = user.tcpClient.GetStream();

            if (m_NetStream != null)
            {

                pendingSends.Add(m_NetStream.WriteAsync(msgOut, 0, msgOut.Length));
            }
            else
            {
                ServerLog("Socket Error: Start at least one client first", Color.red);
            }
        }
    }
    Task.WaitAll(pendingSends.ToArray());
}

(旁注,不确定错误记录是否在正确的位置。我原以为它会在clientList为空时触发)

请注意,我在这里没有做任何涉及线程的事情——这个任务似乎本质上是I/O 绑定的,受我们通过网络发送数据的速度限制。引入更多线程不会改变这一点。

最后,我将从评论中重复一遍:

请注意,TCP 是无穷无尽的字节流,而不是消息。我没有看到您做任何事情来帮助接收者确定您的消息的范围(例如,首先发送长度,或分隔符,或其他消息框架技术)

于 2020-11-17T10:14:04.287 回答