C#客户端-服务器:只有一个客户端接收数据

C# Client-Server: Only one client receives data

我正在尝试调试它,但它在我脑海中变得非常混乱,我真的需要一点帮助。我正在编写具有多个客户端和一个服务器的经典 Chat 应用程序。到目前为止我有什么:

我的问题是关于这第三步,在我的服务器端,我的程序正确输出了这一步。 例如,如果我的用户是 Hugo,他发送 Hey:

Sending hugo: hey
 to System.Net.Sockets.TcpClient0

Sending hugo: hey

 to System.Net.Sockets.TcpClient1

消息被重定向到连接到我的服务器的所有用户。现在问题出在客户端,由于某些原因,消息仅在最后连接的用户 上显示。考虑到前面的示例,消息 "Hey" 将在 TcpClient1 上显示 两次,而在 TcpClient0

永远不会显示

服务器代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using ConsoleApp1;

namespace ServerSide
{

    class Server
    {
        private int port;
        private byte[] buffer = new byte[1024];
        public delegate void DisplayInvoker(string t);
        private StringBuilder msgclient = new StringBuilder();
        private TcpListener client;
        static IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
        private IPAddress ipAddress = host.AddressList[0];
        private TcpClient myclient;
        private List<TcpClient> usersConnected = new List<TcpClient>();



        public Server(int port)
        {
            this.port = port;


        }

        public void startServer()
        {
            client = new TcpListener(ipAddress, port);
            client.Start();
            SERV a = new SERV();
            a.Visible = true;
            a.textBox1.AppendText("Waiting for a new connection...");


            while (true)
            {
                myclient = client.AcceptTcpClient();
                usersConnected.Add(myclient);
                a.textBox1.AppendText("New User connected @" + myclient.ToString() );
                myclient.GetStream().BeginRead(buffer, 0, 1024, Receive, null);
                a.textBox1.AppendText("Size of List " + usersConnected.Count);

            }
        }

        private void Receive(IAsyncResult ar)
        {
            int intCount;

            try
            {
                lock (myclient.GetStream())
                    intCount = myclient.GetStream().EndRead(ar);
                if (intCount < 1)
                {

                    return;
                }
                Console.WriteLine("MESSAGE RECEIVED " + intCount);
                BuildString(buffer, 0, intCount);

                lock (myclient.GetStream())
                    myclient.GetStream().BeginRead(buffer, 0, 1024, Receive, null);
            }
            catch (Exception e)
            {
                return;
            }
        }
        public void Send(string Data)
        {
            lock (myclient.GetStream())
            {
                System.IO.StreamWriter w = new System.IO.StreamWriter(myclient.GetStream());
                w.Write(Data);
                w.Flush();
            }
        }
        private void BuildString(byte[] buffer, int offset, int count)
        {
            int intIndex;
            for (intIndex = offset; intIndex <= (offset + (count - 1)); intIndex++)
            {
                    msgclient.Append((char)buffer[intIndex]);
            }


            OnLineReceived(msgclient.ToString());
            msgclient.Length = 0;

        }
        private void OnLineReceived(string Data)
        {
            int i = 0;

            foreach (TcpClient objClient in usersConnected)
            {
                Console.WriteLine("Sending " + Data + " to " + objClient + i);
                Send(Data);
                i++;
            }
        }



    }
}

客户代码

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.Threading;

namespace WindowsFormsApp2
{
    public partial class Form2 : Form
    {

        private delegate void DisplayInvoker(string t);
        private string currentTopic = null;
        private StringBuilder msg = new StringBuilder();
        static public string MyUser { get; set; }
        static private byte[] buffer = new byte[1024];
        static IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
        static IPAddress ipAddress = host.AddressList[0];
        static Client user = new Client(MyUser, ipAddress, 136);
        public Form2(string User) // when a user is logged in , directly connect him to the server
        {

            InitializeComponent();
            MyUser = User;        
            user.clientConnection();
            Thread readingg = new Thread(reading);
            readingg.Start();
            user.sendText(MyUser + " joined the chatroom!" +"\n");
            IPAdress.Text = GetLocalIP(host);
            IPAdress.ReadOnly = true;
        }
        public void reading()
        {
            user.getClient().GetStream().BeginRead(buffer, 0, 1024, ReadFlow, null);
            Console.WriteLine("READING FUNCTION TRIGGERED FOR "+MyUser);
        }
        private void DisplayText(string t)
        {
            UserChat.AppendText(t);
            Console.WriteLine("DISPLAY FUNCTION TRIGGERED FOR " + MyUser + "with " +msg.ToString());

        }
        private void BuildString(byte[] buffer,int offset, int count)
        {
            int intIndex;
            for(intIndex = offset; intIndex <= (offset + (count - 1)); intIndex++)
            {
                if (buffer[intIndex] == 10)
                {
                    msg.Append("\n");
                    object[] @params = { msg.ToString() };
                    Console.WriteLine("BUILDSTIRNG FUNCTION TRIGGERED FOR " + MyUser);
                    Invoke(new DisplayInvoker(DisplayText),@params);
                    msg.Length = 0;
                }
                else
                {
                    msg.Append((char)buffer[intIndex]);
                }
            }
        }
        private void ReadFlow(IAsyncResult ar)
        {

            int intCount;

            try
            {

                intCount = user.getClient().GetStream().EndRead(ar);
                Console.WriteLine(intCount);
                if (intCount < 1)
                {
                    return;
                }
                Console.WriteLine(MyUser + "received a message");
                BuildString(buffer, 0, intCount);

                user.getClient().GetStream().BeginRead(buffer, 0, 1024, this.ReadFlow, null);

            }catch(Exception e)
            {
                return;
            }
        }
        private string GetLocalIP(IPHostEntry host)
        {

            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    return ip.ToString();
                }
            }

            return "192.168.1.1";
        } // get your local ip
        private void label1_(object sender, EventArgs e)
        {
            this.Text = "Hello " + MyUser;
        }
        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
        private void UserMessage_TextChanged(object sender, EventArgs e)
        {

        }
        private void UserMessage_Focus(object sender, EventArgs e)
        {
            UserMessage.Text = "";
        }       
        private void UserMessage_Focus2(object sender, EventArgs e)
        {

        }
        private void button2_Click(object sender, EventArgs e)
        {
            listBox1.Items.Add(addTopic.Text);
            addTopic.Text = "Add Topic";
        }
        private void button2_(object sender, EventArgs e)
        {

        }
        private void addTopic_(object sender, EventArgs e)
        {

        }
        private void addTopic_TextChanged(object sender, EventArgs e)
        {

        }
        private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            string curItem = listBox1.SelectedItem.ToString();
            label1.Text = "Topic "+curItem;
            currentTopic = curItem;
        }
        private void IPAdress_TextChanged(object sender, EventArgs e)
        {

        }
       // send msg to the server
        private void UserChat_TextChanged(object sender, EventArgs e)
        {

        }
        private void Form2_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //Handle event here
            System.Windows.Forms.Application.Exit();
        }
        private void Send_Click_1(object sender, EventArgs e)
        {
            user.sendText(MyUser + ": " + UserMessage.Text +"\n");
            UserMessage.Text = " ";
        }//send message
    }
}

OnLineReceived 中,对于您调用 SendData 的每个客户,您发送给 myclient。您可能想将 objClient 传递给 SendData,然后发送给 that.

注意这里也有一些线程问题;例如,如果有人 恰好在 您正在迭代列表时连接,它将破坏迭代器。