C # клиент-сервер: только один клиент получает данные - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь отладить это, но у меня в голове становится очень грязно, мне действительно нужна небольшая помощь здесь.Я делаю классическую прикладную программу чата с несколькими клиентами и сервером .Что у меня пока что:

  • Клиенты подключаются к серверу;
  • Сервер сохраняет каждого клиента в списке;
  • Когда клиент отправляет сообщение, онзатем отправляется всем клиентам в списке;

Моя проблема связана с этим третьим шагом, на моей стороне сервера моя программа выводит шаг правильно.Например, если мой пользователь - Хьюго, и он посылает Hey:

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

Sending hugo: hey

 to System.Net.Sockets.TcpClient1

Сообщение перенаправляется всем пользователям, подключенным к моему серверу.Теперь проблема на стороне клиента, по некоторым причинам, сообщение отображается только для подключенного пользователя LAST .Учитывая предыдущий пример, сообщение «Эй» будет отображаться два раза на 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 голосов
/ 04 декабря 2018

В OnLineReceived, для каждого клиента вы звоните SendData, куда вы отправляете myclient.Вы, вероятно, хотите передать objClient в SendData и отправить , что .

Обратите внимание, что там также есть некоторые проблемы с потоками;если кто-то подключит точно в то время, когда вы перебираете список, он сломает итератор, например.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...