簡體   English   中英

C#TCP服務器到多客戶端(正在監聽的客戶端數量未知)

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

我正在嘗試編寫一個由服務器和某些客戶端構建的小程序。 服務器將向客戶端傳輸/推送一條文本消息(不允許該客戶端發送回服務器,所有客戶端都應從服務器獲得相同的文本消息)我在這里看到了與此主題有關的一些問題,通過網絡,但沒有得到我正在尋找的確切解決方案。 大多數解決方案是為每個客戶端創建一個線程。 但是讓我們假設我並不總是知道在特定時間會有多少客戶在聽。 可以是2,也可以是30。我知道有一種方法可以創建一個線程池,並讓.NET處理線程分配,但是從來沒有很好的實踐,也沒有我對Threading的知識。 現在,我有一個簡單的Sever to Client程序,該程序可以按預期運行,但只能在一個客戶端上運行。 所以這是我的代碼:

服務器:

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

客戶:

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

任何幫助都可以! :)

我認為首先應該在應用程序的開頭啟動監聽器。 然后在間隔(Timer)中查找傳入的連接(TCPListener.Pending http://msdn.microsoft.com/de-de/library/system.net.sockets.tcplistener.pending(v=vs.110).aspx )如果獲得連接后,應將TCPClient保存在列表中。 在按鈕上單擊將消息發送給您的客戶。

我認為這不是最好的解決方案,但是它是沒有多線程的;-)

我編寫了一些示例代碼,希望對您有所幫助(未經測試):

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