【问题标题】:Send out message from server to all clients c#?从服务器向所有客户端c#发送消息?
【发布时间】:2017-11-08 15:28:06
【问题描述】:

我尝试使用 C# 在控制台中创建服务器程序。我使用 ThreadPool 为每个客户端创建单独的套接字。然后,我创建一个 static List<TcpClient> clients = new List<TcpClient>();to 包含所有连接到的客户端。

然后,我想要的是,当 1 个客户端向服务器发送消息时,服务器将接收并将其发送给所有连接的客户端。所以,我写道:

foreach (var item in clients)
{
   ns.Write(data, 0, recv);
   //send message to all client
}

但是,只有刚刚发送消息的客户端才能收到,其他客户端什么也没有收到!

**** 服务器端:

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
class ThreadedTcpSrvr
{
    private TcpListener client;

    //private 

    public ThreadedTcpSrvr()
    {
        client = new TcpListener(IPAddress.Parse("127.0.0.1"), 9050);
        client.Start();
        Console.WriteLine("Waiting for clients...");
        while (true)
        {
            while (!client.Pending())
            {
                Thread.Sleep(1000);
            }
            ConnectionThread newconnection = new ConnectionThread();
            newconnection.threadListener = this.client;
            Thread newthread = new Thread(new
                 ThreadStart(newconnection.HandleConnection));
            newthread.Start();
        }
    }
    public static void Main()
    {
        ThreadedTcpSrvr server = new ThreadedTcpSrvr();
    }
}
class ConnectionThread
{
    static List<TcpClient> clients = new List<TcpClient>();
    public TcpListener threadListener;
    private static int connections = 0;
    public void HandleConnection()
    {
        int recv;
        byte[] data = new byte[1024];
        TcpClient client = threadListener.AcceptTcpClient();
        NetworkStream ns = client.GetStream();
        //TcpClient clientSocket = client.AccepTcpClient();
        clients.Add(client);
        connections++;
        Console.WriteLine("New client accepted: {0} active connections",
                 connections);
        string welcome = "Welcome to my test server";
        data = Encoding.ASCII.GetBytes(welcome);
        ns.Write(data, 0, data.Length);
        while (true)
        {
            data = new byte[1024];
            recv = ns.Read(data, 0, data.Length);
            if (recv == 0)
                break;
            Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
            //ns.Write(data, 0, recv);
            foreach (var item in clients)
            {
                ns.Write(data, 0, recv);
                //send message to client
            }
        }
        ns.Close();
        client.Close();
        connections--;
        Console.WriteLine("Client disconnected: {0} active connections",connections);
    }
}

**** 客户端:

void ReceiveData(IAsyncResult iar)
{
   try
   {
       while(true)
       {
          Socket remote = (Socket)iar.AsyncState;
          int recv = remote.EndReceive(iar);
          string stringData = Encoding.ASCII.GetString(data, 0, recv);
          ListAddItem(stringData);
       }
   }
   catch
   {

   }

}

【问题讨论】:

  • 因为 ns.write 在您的客户端循环中 - 您没有为每个客户端使用套接字,而是您收到的那个。当你之前问基本相同的问题时,你被暗示了
  • 在 for 循环中执行 item.Write(data, 0, recv);。
  • @FrankNielsen,你的意思是item.GetStream().Write(..)
  • 不能使用 item.Write(data, 0, recv);因为 TcpClient 不包含 Write() 方法。
  • 一般来说,thread-per-socket 不能很好地扩展。你最好使用某种形式的异步(有许多用于套接字的选项)并让窗口在那些小场合借给你 I/O 线程,当线程有一些有用的事情要做时,例如处理已经(终于!)通过网络到达的充满数据的缓冲区。

标签: c# multithreading threadpool


【解决方案1】:

您的 ns(网络流基于每个客户端)

在以下代码中,您的 ns 用于传入客户端。因此,您正在遍历所有客户端,但只与当前传入的客户端交谈

        foreach (var item in clients)
        {
            ns.Write(data, 0, recv);
            //send message to client
        }

同意@Damien_The_Unbeliever,这适用于少数客户端,但是当您开始扩展超过 2000 个客户端时,您会遇到性能问题。随着线程切换和需要打开的端口数量。最好使用基于事件/异步的架构

【讨论】:

    猜你喜欢
    • 2015-06-20
    • 2016-07-13
    • 2017-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多