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

时间:2018-12-04 13:09:21

标签: c# server client

我正在尝试调试它,但是我的脑海变得一团糟,在这方面我确实需要一点帮助。我正在使用具有多个客户端和一台服务器的经典的“聊天应用程序”。到目前为止,我有什么:

  • 客户端连接到服务器;
  • 服务器将每个客户端存储在一个列表中;
  • 当客户端发送一条消息时,它将被发送到列表中的所有客户端;

我的问题与第三步有关,在服务器端,我的程序正确输出了该步骤。 例如,如果我的用户是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
    }
}

1 个答案:

答案 0 :(得分:2)

OnLineReceived中,对于每个呼叫SendData的客户,您都将其发送到myclient。您可能想将objClient传递到SendData中,然后发送给那个

请注意,那里也存在一些线程问题;例如,如果某人恰好在您访问列表时连接,则它将中断迭代器。