Как написать на нескольких QTcpSockets, используя QThreads?
Пару дней я боролся с этой проблемой на QTcpSockets и QThreads.
У меня есть QTcpServer, который прослушивает порт и создает нового клиента с помощью nextPendingConnection(). Так что теперь у клиента есть qtcpsocket, который я могу использовать для чтения и записи.
Предположим, у меня есть 100 клиентов, подключенных к моему серверу. Когда один из них хочет передать сообщение всем, мой основной поток (где я создаю клиентов с помощью nextPendingConnection()) должен будет перебрать более 100 клиентов и вызвать метод write для их сокетов. Если, например, 10 пользователей одновременно вещают, мне придется сделать 1000 итераций, поэтому, на мой взгляд, на стороне клиента будет некоторая задержка (когда пользователь получит сообщения).
Я хотел бы сделать все записи сокетов в отдельных потоках, чтобы я мог отправлять данные в параллельном режиме. Я знаю, что не могу вызвать сокет из другого потока из того, в котором он был создан, и я не хочу использовать один поток для каждого клиента, потому что я не знаю, хорошо ли иметь много потоков (кроме того, эти потоки должны работать всегда, если клиент не отключается).
Я читал пример сервера потока удачи, но он не отвечает моей проблеме, потому что они разрушают сокет после отправки данных; Я не хочу разрушать свой сокет, потому что я должен прослушивать входящие сообщения (чтобы я мог их транслировать).
Одна вещь, о которой я думал, - это иметь 2 сокета для каждого клиента (на сервере и на стороне клиента); так что я оставляю один сокет для чтения, а другой могу использовать как в примере с сервером потока удачи; в этом случае я бы также использовал пул потоков, чтобы ограничить количество задач (в противном случае это было бы то же самое, что использование одного потока на клиента).
Не могли бы вы указать мне правильное направление или дать несколько советов о том, как реализовать запись сокетов paralel без фактического наличия одного потока на клиента...?
С уважением,
Себастьян
1 ответ
Есть функция "WriteToSocket", которая записывает данные в конкретный сокет. Также есть очередь, в которой хранятся данные для сокета, защищенные мьютексом. В функцию добавьте данные, которые вы хотите отправить в очередь для сокета. Проверьте, назначен ли сокет потоку (для этого сохраните флаг). Если так, то все готово. Если нет, запланируйте задание в пул потоков, чтобы отправить данные из сокета.
В зависимости от множества деталей, вы можете предпочесть альтернативную реализацию. В этой реализации логика отправки для каждого сокета имеет два режима: в очереди и без очереди. Розетки начинаются без очереди. Если вы хотите отправить в сокет, приобретите блокировку, которая защищает его. Если он находится в режиме очереди, добавьте данные в очередь, и все готово.
Если вы находитесь в режиме без очереди, попробуйте отправить данные с неблокирующей отправкой. Если вы отправите все это, все готово. В противном случае сохраните неотправленные данные в очередь и переведите сокет в режим очереди.
Вам нужно будет организовать какой-то механизм для "периодической" попытки отправки данных на сокеты в режиме очереди. Обычно это можно сделать с помощью команды "выбрать" или "опрос". С QTcpSockets у вас есть сигналы и слоты.