c многопоточный tcp сервер

Рассмотрим, как создать многопоточное клиент-серверное приложение. Фактически оно будет отличаться от однопоточного только тем, что обработка запроса клиента будет вынесена в отдельный поток.

Вначале создадим проект для клиента. Назовем проект ConsoleClient и в классе Program определим следующий код:

В программе клиента пользователь будет вначале вводить свое имя, а затем сообщение для отправки. Причем сообщение будет уходить в формате Имя: сообщение .

После отправки сообщения клиент получает сообщение с сервера.

Теперь создадим проект сервера, который назовем ConsoleServer. Вначале в проект сервера добавим новый класс ClientObject , который будет представлять отдельное подключение:

В этом классе, наоборот, сначала получаем сообщение в цикле do..while и потом немного его изменяем (отрезаем по двоеточию и переводим в верхний регистр) и отправляем обратно клиенту. То есть класс ClientObject заключает в себе все действия по работе с отдельным подключением.

В главном классе проекта сервера определим следующий код:

Сразу после подключения нового клиента:

Создается объект ClientObject и новый поток, который запускает метод Process объекта ClientObject, где собственно и происходит получение и отправка сообщений. Таким образом, сервер сможет одновременно обрабатывать сразу несколько запросов.

Результаты работы программы. Один из клиентов:

4 Eddie [2011-02-23 00:23:00]

Мой TCP-сервер прослушивает порт 5003. Когда соединение выполняется, я хочу создать поток и запустить функцию interpMessage. У меня есть несколько вопросов об этом.

1) Я делаю вызов malloc и бесплатно в правильных местах?

2) После вызова pthread_create мой код сразу переходит к «free (child)»; а затем вернуться к началу цикла while?

3) Что произойдет, если 5 человек подключится в одно и то же время (как работает код для создания 5 потоков?)

c multithreading tcp client

1 ответ

Ваш код правильно использует malloc и free , но способ, которым вы это делаете, делает реализацию более сложной, чем это необходимо. Функция pthread_create работает, записывая идентификатор нового потока в память, на которую указывает первый параметр. В вашем случае вы динамически выделили этот буфер, а затем немедленно освободили его. Следовательно, память привязана к одной итерации цикла while . Если это то, что вы хотите, вам, вероятно, лучше просто сделать выделенное стек pthread_t и передать указатель на него в pthread_create :

Теперь, когда child локально привязан к циклу, управление памятью будет обрабатываться автоматически без необходимости вызова malloc или free .

Что касается второго вопроса о том, продолжает ли элемент управления free (child) , а затем возвращается в верхнюю часть цикла после вызова pthread_create , да, это правильно. Будет создан второй поток, выполняющий interpretMessage , поэтому может произойти некоторая задержка, если исходный процесс задерживается, но контроль возобновляется с этой точки.

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

Одна вещь, которую я заметил в вашем коде — когда вы создаете поток для вызова interpretMessage , вы не указали никаких аргументов функции, и поэтому каждый поток будет работать без какого-либо контекста для того, как он был создан, Было ли это намеренно?

Нужно написать сервер для приёма данных от разных по типу устройств с подтверждением приёма. Устройства присылают разные данные и алгоритм общения с каждым типом устройств разный. Из-за скудного знания с++ столкнулся с проблемой реализации. Я хочу пойти по следующему пути: запускаю служащий сервер. При приеме данных (первый пакет устройства — идентификатор типа устройства и его номер) созданный сокет отправляется в отдельный поток и дальше идёт обработка данных определённого устройства в отдельном потоке. Проблема: у меня есть класс с алгоритмом обработки пакетов идентификаторов и создание общего сокета. После создания экземпляра и приёма нужного пакета идентификатора не знаю как передать данный сокет в новый поток с новым алгоритмом обработки пакетов. Делаю это я для того, чтобы уменьшить длину передаваемых данных и снизить нагрузку на процессор (избавлюсь от множества условных операторов при каждом принятом пакете). Возможно у меня неправильная логика, поэтому прошу направить на правильный алгоритм. Моя реализация многопоточности: создаю экземпляр Qthread и с помощью MoveToThread передаю экземпляр с сокетом и обработки данных устройства. С потоками я ещё не до конца разобрался. Насколько я понял, в qt можно создать поток и поместить в него объект и только ловить сигналы от потока.

Оцените статью