WOLF 2018 Ответов: 2

Проблема Tcp сервера со случайными соединениями


Послушайте, я пытаюсь сделать TCP-сервер для частного чата с шифрованием AES.
но проблема, с которой я сталкиваюсь, заключается в том, что когда один клиент присоединяется, он работает нормально. но когда двое присоединяются, это становится странным, как если бы новый клиент присоединился даже тогда, когда они соединены только двумя клиентами. я пытался это исправить, но безуспешно. кроме того он никогда не отправляет сообщение клиенту

Я считаю, что проблема заключается в функции is

public static void Brodcast_Message(TcpClient tcp, string message)
        {
            for(int i = 0; i < clients.Count; i++)
            {
                if(tcp != clients[i])
                {
                    Console.WriteLine(clients[i].Connected);
                    if (clients[i].Connected)
                    {
                        byte[] buffer = Encoding.ASCII.GetBytes(message);
                        Stream stream = clients[i].GetStream();
                        stream.Write(buffer, 0, buffer.Length);
                        stream.Flush();
                        Console.WriteLine($"Send Message: {message}");
                    }
                    else
                    {
                        clients.RemoveAt(i);
                        threads[i].Abort();
                        threads.RemoveAt(i);
                        Console.WriteLine("Client Disconnected");
                    }
                }
            }
        }


вот что такое "потоки" и "клиенты"

public static List<TcpClient> clients = new List<TcpClient>();
public static List<Thread> threads = new List<Thread>();


это клиентский поток

public static void Client_Thread(TcpClient client)
        {
            bool exit = true;
            while (exit)
            {
                try
                {
                    byte[] buffer = new byte[500];
                    Stream stream = client.GetStream();
                    stream.Read(buffer, 0, buffer.Length);
                    string messsage = Encoding.ASCII.GetString(buffer).Replace("\0", "");
                    if (!String.IsNullOrEmpty(messsage))
                    {
                        Console.WriteLine($"MSG: {messsage}");
                        Brodcast_Message(client, messsage);
                    }
                }
                catch (Exception) { exit = false; }
            }
        }


это отправная точка

static void Main(string[] args)
        {
            listener.Start(100);
            while (true)
            {
                TcpClient client = listener.AcceptTcpClient();
                Thread thread = new Thread(() => Client_Thread(client));
                clients.Add(client);
                threads.Add(thread);
                Console.WriteLine("Client Connected");
                thread.Start();
            }
        }


что касается клиента

public static void Server_Thread(ListBox Users, ListBox Messages)
        {
            while (true)
            {
                try
                {
                    client = new TcpClient("127.0.0.1", 2355);
                    while (true)
                    {
                        Stream sw = client.GetStream();
                        byte[] buffer = new byte[500];
                        sw.Read(buffer, 0, buffer.Length);
                        string encoded_data = Decrypt(Encoding.ASCII.GetString(buffer), "YOUR_PASSWORD");
                        MessageBox.Show(encoded_data);
                        string[] data = encoded_data.Split(':');
                        if (!String.IsNullOrEmpty(encoded_data))
                        {
                            if (!User_Check(data[0], Users))
                            {
                                Users.Invoke((MethodInvoker)delegate { Users.Items.Add(data[0]); });
                            }
                            else if (data[0] == "SYSTEM")
                            {
                                Users.Invoke((MethodInvoker)delegate { Users.Items.Remove(data[1]); });
                            }
                            else
                            {
                                Messages.Invoke((MethodInvoker)delegate { Messages.Items.Add($"{data[0]} >> {data[1]}"); });
                            }
                        }
                    }
                }
                catch (Exception) { }
            }
        }


Что я уже пробовал:

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

2 Ответов

Рейтинг:
8

WOLF 2018

я все исправил. это было с помощью

User_Check(data[0], Users)
проверка, которую я сделал, разбила клиент и отключила его без сообщения об ошибке


Рейтинг:
2

Richard MacCutchan

У меня нет времени анализировать весь ваш код, но следующее выглядит немного странно:

if(tcp != clients[i]) // if not the client we want ... ?
{

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


WOLF 2018

ну это проверяет чтобы убедиться что отправитель сообщения не получит свое собственное сообщение обратно