简体   繁体   English

C#TCP服务器到多客户端(正在监听的客户端数量未知)

[英]C# TCP Server to Multi Clients (Unknown number of clients listening)

I'm trying to write a small program that is built from a Server and some Clients. 我正在尝试编写一个由服务器和某些客户端构建的小程序。 the Server will transfer / push a Text Message to the clients (the client not allowed to send back to the server, all of the clients should get the same Text Message from the server) I've seen some question about this subject around here and over the net but did not get the exact solution I'm looking for. 服务器将向客户端传输/推送一条文本消息(不允许该客户端发送回服务器,所有客户端都应从服务器获得相同的文本消息)我在这里看到了与此主题有关的一些问题,通过网络,但没有得到我正在寻找的确切解决方案。 most of the solutions were to create a thread for each client. 大多数解决方案是为每个客户端创建一个线程。 but lets assume that I don't always know how many clients will be listening on a certain time. 但是让我们假设我并不总是知道在特定时间会有多少客户在听。 could be 2 and could be 30. I know there's a way of making a Thread pool and let .NET deal with assigning the threads but never had a good practice with that nor my knowledge with Threading is any good. 可以是2,也可以是30。我知道有一种方法可以创建一个线程池,并让.NET处理线程分配,但是从来没有很好的实践,也没有我对Threading的知识。 for now I have a simple Sever to Client program that works as expected but again, only with one client. 现在,我有一个简单的Sever to Client程序,该程序可以按预期运行,但只能在一个客户端上运行。 so here is my code: 所以这是我的代码:

Server: 服务器:

using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows;

namespace NetMessageServerWpf
{
    public partial class MainWindow : Window
    {
        TcpClient client;

        public MainWindow()
        {
            InitializeComponent();
            this.tcpListener = new TcpListener(IPAddress.Any, 3000);
            this.listenThread = new Thread(new ThreadStart(ListenForClients));
            this.listenThread.Start();
        }

        private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            if(client == null || !client.Connected)
                client = this.tcpListener.AcceptTcpClient();
            msg = txtMessage.Text;
            SendTCP(client);
        }

        public TcpListener tcpListener;
        public Thread listenThread;

        private string msg;

        private void ListenForClients()
        {
            this.tcpListener.Start();
        }

        public void SendTCP(TcpClient tcpClient)
        {
            NetworkStream clientStream = tcpClient.GetStream();
            ASCIIEncoding encoder = new ASCIIEncoding();
            byte[] buffer = encoder.GetBytes(this.msg);
            clientStream.Write(buffer, 0, buffer.Length);
            clientStream.Flush();
        }
    }
}

Client: 客户:

using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace NetClientSideWpf
{
    class Client : Base
    {

        private string messageString;
        public string MessageString
        {
            get { return messageString; }
            set
            {
                messageString = value;
                OnPropertyChanged("MessageString");
            }
        }


        public Client()
        {
            ConnectToServer();
        }

        public void ConnectToServer()
        {
            TcpClient client = new TcpClient();

            IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000);

            client.Connect(serverEndPoint);


            NetworkStream clientStream = client.GetStream();

            Thread ServerThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
            ServerThread.Start(client);


        }

        private void HandleClientComm(object client)
        {
            TcpClient tcpClient = (TcpClient)client;
            NetworkStream clientStream = tcpClient.GetStream();

            byte[] message = new byte[4096];
            int bytesRead;

            while (true)
            {
                bytesRead = 0;

                try
                {
                    bytesRead = clientStream.Read(message, 0, 4096);
                }
                catch
                {
                    break;
                }

                if (bytesRead == 0)
                {
                    break;
                }

                ASCIIEncoding encoder = new ASCIIEncoding();
                MessageString = encoder.GetString(message, 0, bytesRead);
            }
        }
    }
}

any help will do! 任何帮助都可以! :) :)

I think first you should start your Listener at the start of your Application. 我认为首先应该在应用程序的开头启动监听器。 Then look in intervals (Timer) for ingoing connections (TCPListener.Pending http://msdn.microsoft.com/de-de/library/system.net.sockets.tcplistener.pending(v=vs.110).aspx ) If you get a Connection you should save the TCPClient in a List. 然后在间隔(Timer)中查找传入的连接(TCPListener.Pending http://msdn.microsoft.com/de-de/library/system.net.sockets.tcplistener.pending(v=vs.110).aspx )如果获得连接后,应将TCPClient保存在列表中。 On Button Click send the Messages to your Clients. 在按钮上单击将消息发送给您的客户。

I think it is not the best solution but it is one without Multiple Threads ;-) 我认为这不是最好的解决方案,但是它是没有多线程的;-)

I wrote some sample code, hope this help you (not tested): 我编写了一些示例代码,希望对您有所帮助(未经测试):

public partial class MainWindow : Window
{

    private TcpListener _server;
    private List<TcpClient> _connectedClients;

    public MainWindow()
    {
        InitializeComponent();

        _server = new TcpListener(IPAddress.Any, 3000);
        _connectedClients = new List<TcpClient>();
        _server.Start();

        DispatcherTimer timer = new DispatcherTimer();
        timer.Interval = TimeSpan.FromSeconds(1); //every 1 sec!
        timer.Tick += timer_Tick;
        timer.Start();
    }

    private void SendMessage(string message)
    {
        ASCIIEncoding encoder = new ASCIIEncoding();
        byte[] buffer = encoder.GetBytes(message);
        foreach (var client in _connectedClients)
        {
            NetworkStream clientStream = client.GetStream();
            clientStream.Write(buffer, 0, buffer.Length);
            clientStream.Flush();
        }
    }


    void timer_Tick(object sender, EventArgs e)
    {
        Debug.WriteLine("Tick");
        Title = "hello";

        if (_server.Pending())
        {
            _connectedClients.Add(_server.AcceptTcpClient());
        }
    }

}

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

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