TCP服务器上的多线程消息发送

Multithread message send on TCP server

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

谢谢大家

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;
            }
        }
    }
}

如果您想同时发送给多个客户端,我建议使用 WriteAsync 变体。我也会按照评论中的建议,移动创建缓冲区以发送出循环。

目前你不会return从broadCast发送所有消息,我在下面将其实现为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 绑定,受我们通过线程发送数据的速度限制网络。引入更多线程不会改变这一点。

最后,我再重复一下评论:

be aware that TCP is an endless stream of bytes, not messages. I'm not seeing you do anything to assist the receiver with determining the extent of your message (by e.g. sending the length first, or delimiters, or other message framing techniques)