0

Пытаюсь написать некоторое подобие чата на c# с использованием windows form. Есть два приложения - сервер и клиент. Сервер стартует на ip 127.0.0.1 и порте 8085. Хранит список подключений кастомного класса, который инициализируется именем, стримом и id. То есть получается, что клиент посылает сообщения вида operation/имя. При коннекте к серверу, клиент отправляет строку connect/nickname. Сервер создает объект клиента, связывает его со стримом и ником, и добавляет в список клиентов вот так

 public void listenClient()
        {
        TcpClient client = tcpListener.AcceptTcpClient();


        NetworkStream stream = client.GetStream();
        int i = 0;

        while (true)
        {

            string str;
            string message;

            str = getMessage(stream);
            string[] words = str.Split('/');
            string command = words[1];
            string nickname = words[2];

            if (command == "connect")
            {
                ClientClass tmp = new ClientClass(nickname, stream);
                addConnection(tmp);
            }

            if (command == "close")
            {
                delConnection(nickname);
                break;

            }

            System.Threading.Thread.Sleep(100);


            //client.Close();

        }

}

Если клиент отправляет close то он удаляется из списка и его "прослушивание" прекращается. Что бы как-то отслеживать работу сервера, я создал форму listbox, у сервера создал член класса static ListBox listBox; По нажатию кнопки старт, я отправляю форму в метод класса и он инициализируется формой и стартует:

private void button2_Click(object sender, EventArgs e)
       {
           server.initForm(listBox1);
           server.start();
   }

Так же есть метод renderBox,который обновляет форму,если какой-то клиент подключился или отключился

public void renderBox()
        {
        listBox.Items.Clear();
        foreach (var Item in listClient)
        {
            listBox.Items.Add(Item.name + " " + Item.id);
        }
        listBox.Refresh();
    }

Проблема в том,что это работает только с одним клиентом последовательно, второй обслуживается лишь тогда,когда уйдет первый. Я попробовал вынести прослушивание клиента в отдельный метод,который я уже скидывал выше( listenClient() ), а в главном методе start сервера написал вот так:

public void start()
        {
            tcpListener = new TcpListener(IPAddress.Parse(ip), port);
            tcpListener.Start();
        while (true)
        {

            Thread myThread = new Thread(new ThreadStart(listenClient));
            myThread.Start();





        }


    }

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

aepot
  • 49,560
DLevg
  • 103
  • 2
    У вас смешались кони, люди и при этом хвост виляет собакой. Почему сервер создает UI? Почему бы UI не опрашивать сервер? Сама проблема у вас в том, что операции с UI элементами могут выполняться только в том потоке, где эти элементы были созданы. Подобных просблем тут на сайте полно, просто воспользуйтесь поиском. Но я бы посоветовал перепродумать свю архитектуру. – tym32167 Dec 02 '20 at 21:32
  • Я раньше никогда не работал с потоками, поэтому прошу вашей помощи - Начните читать. Потоки: 1, 2, на английском – aepot Dec 02 '20 at 21:36
  • 1
    Сделайте сервер консольным, пусть он пишет логи на экран и в файл, это самое простое решение. А клиенты делайте уж как вам нравится. – aepot Dec 02 '20 at 21:43

0 Answers0