如何使我的客户端 - 服务器应用程序成为多客户端 - 服务器应用程序? C#

时间:2015-02-20 10:39:38

标签: c# .net

我在为多个客户端使用设置客户端 - 服务器应用程序时遇到了一些问题。我可以连接到服务器并使用一个客户端。我修改了一些代码以通过第二个客户端连接,但我真的不知道如何从第二个客户端读取和发送数据到第一个客户端和服务器中也可见。任何想法/帮助?提前谢谢!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;

namespace Server_WF
{
    public partial class Form1 : Form
    {
        private TcpClient client;
        static List<TcpListener> listeners = new List<TcpListener>(); 
        public StreamReader SR;
        public StreamWriter SW;
        public string otrzymano;
        public String msg;

        public Form1()
        {
            InitializeComponent();

            IPAddress[] localIP = Dns.GetHostAddresses(Dns.GetHostName());  // Pobieranie własnego IP
            foreach(IPAddress adres in localIP)
            {
                if (adres.AddressFamily == AddressFamily.InterNetwork)
                {
                    textBox3.Text = adres.ToString();
                }
            }
        }

        private void button2_Click(object sender, EventArgs e) // START SERVER
        {
            TcpListener listener = new TcpListener(IPAddress.Any, int.Parse(textBox4.Text));
            listeners.Add(listener);
            listener.Start();
            client = listener.AcceptTcpClient();
            SR = new StreamReader(client.GetStream());
            SW = new StreamWriter(client.GetStream());
            SW.AutoFlush = true;

            backgroundWorker1.RunWorkerAsync();                     // Rozpocznij odbieranie danych
            backgroundWorker2.WorkerSupportsCancellation = true;    // Zdolność do usunięcia wątku

        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) // Odbieranie danych
        {
            while(client.Connected)
            {
                try
                {
                    otrzymano = SR.ReadLine();
                    this.textBox2.Invoke(new MethodInvoker(delegate() { textBox2.AppendText("Ktoś: " + otrzymano + "\n"); }));
                    otrzymano = "";
                }
                catch(Exception x)
                {
                    MessageBox.Show(x.Message.ToString());
                }
            }
        }

        private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e) // Przesyłanie danych
        {
            if(client.Connected)
            {
                SW.WriteLine(msg);
                this.textBox2.Invoke(new MethodInvoker(delegate() { textBox2.AppendText("Ja: " + msg + "\n"); }));
            }
            else 
            {
                MessageBox.Show("Wysyłanie nie powiodło się.");
            }
            backgroundWorker2.CancelAsync();
        }

        private void button3_Click(object sender, EventArgs e)  // Połącz z serwerem
        {
            client = new TcpClient();
            IPEndPoint IP_End = new IPEndPoint(IPAddress.Parse(textBox5.Text), int.Parse(textBox6.Text));

            try 
            {
                client.Connect(IP_End);
                if(client.Connected)
                {
                    textBox2.AppendText("Połączono z serwerem..." + "\n");
                    SW = new StreamWriter(client.GetStream());
                    SR = new StreamReader(client.GetStream());
                    SW.AutoFlush = true;

                    backgroundWorker1.RunWorkerAsync();                     // Rozpocznij odbieranie danych
                    backgroundWorker2.WorkerSupportsCancellation = true;    // Zdolność do usunięcia wątku
                }
            }
            catch(Exception x)
            {
                MessageBox.Show(x.Message.ToString());
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if(textBox1.Text != "")
            {
                msg = textBox1.Text;
                backgroundWorker2.RunWorkerAsync();
            }
            textBox1.Text = "";
        }
    }
}

1 个答案:

答案 0 :(得分:0)

亲爱的,你的代码还有很多工作要做。首先:不要从后台工作人员代码中调用CancelAsync。这不是必要的,可能会引起问题。此外,后台工作人员永远不应该显示MessageBoxes

其次,在这种情况下,后台工作者不是正确的工具!

第三:您需要使您的代码完全异步。所以请查看BeginAcceptTcpClient。然后,在自己的线程中处理每个连接的客户端(非后台工作者!)。

关于如何做到这一点的例子,谷歌可能是最好的,因为这在这里写得太多了。