简体   繁体   中英

c# Server role with multi type clients

I'm trying to built a server client application (wpf).

the structure I'm trying to accomplish is this:

  1. a client that only sends data( a simple string) needs to be a wpf app.
  2. a client that only receives data(a string from the sender client)
  3. a server that transfer the data from the sender to the receiver (can be multiple senders and multiple receivers) can be a console application.

One of the problems I'm facing is how do I separate the server role.

The second problem is how do I let the server know what type of client it's communicating with, a sender or a receiver.

this 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:

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

Thanks in advance! :)

First off, I would wrap your clients in a Client object that you can call methods on.

Then, when a client connects, it should send out a message detailing its mode:

"IAm:Sender"

OR

"IAm:Reciever"

You could have the second part parse to an enum if you wanted. Then you would sort the Client objects based on the mode:

List<Client> clients;

client.Mode = Enum.Parse(typeof(ClientMode), message.Split(':')[1]);
clients.Add(client);

And when a "sender" sent a "Broadcast" message, you would write it to every Client object in the recievers list. This would be in the client read thread

if (sender.Type == ClientMode.Sender)
{
    foreach (Client client in clients.Where(c => c.Type == ClientMode.Sender)
        client.Send(message)
}

Obviously these are very broad strokes, and the full implementation would be far too large for SO. Hopefully that gets you on the right track, please let me know if I can clarify anything!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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