Инструменты пользователя

Инструменты сайта


develop:qt:network

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
develop:qt:network [2021/09/29 06:58]
admin
develop:qt:network [2021/10/27 04:33] (текущий)
admin
Строка 8: Строка 8:
  
 ===== QTcpServer ===== ===== QTcpServer =====
------ 
 Позволяет принимать Tcp-соединения, порт можно выбрать либо авто, IP так же можно выбрать конкретный либо все IP хоста.\\ Позволяет принимать Tcp-соединения, порт можно выбрать либо авто, IP так же можно выбрать конкретный либо все IP хоста.\\
  
Строка 20: Строка 19:
  
 ===== QAbstractSocket ===== ===== QAbstractSocket =====
------ 
 {{ :develop:qt:qnet_0.png?direct&300|}} {{ :develop:qt:qnet_0.png?direct&300|}}
  
Строка 100: Строка 98:
 Внутри создаем объект пользовательского подключения, методом **nextPendingConnection()**, и работаем с этим сокетом подключения, отправляемые данные просто пишем в него, как в устройство (QIODevice).\\ Внутри создаем объект пользовательского подключения, методом **nextPendingConnection()**, и работаем с этим сокетом подключения, отправляемые данные просто пишем в него, как в устройство (QIODevice).\\
 Запись делаем методом **write()**, на сколько я понял разделение на пакеты происходит уже на уровне протокола, в зависимости от размера данных, и неважно сколько раз мы вызываем write().\\ Запись делаем методом **write()**, на сколько я понял разделение на пакеты происходит уже на уровне протокола, в зависимости от размера данных, и неважно сколько раз мы вызываем write().\\
 +Пакеты по 60-65 кБ.\\
  
 В данном примере открываем файл и заносим его содержимое в массив **QByteArray**, можно сразу целиком, можно частями, с указанным размером (чтение автоматом продолжается с нужного места) В данном примере открываем файл и заносим его содержимое в массив **QByteArray**, можно сразу целиком, можно частями, с указанным размером (чтение автоматом продолжается с нужного места)
Строка 376: Строка 375:
 </code> </code>
 </details> </details>
 +
 +
 +
 +===== Еще пример клиент/сервера =====
 +Сервер поддерживает **множественное подключение**, для **каждого соединения** создается **собственный контекст**, с собственными **буферами**\\
 +
 +При передаче, данные делятся на пакеты дважды, типа программные и физические.\\
 +**Программные** формируются при каждом вызове метода **write()**, если писать через **QDataStream** в **QByteArray**, то перед каждой записью в датастрим будет автоматом добавлено интовое значение, с указанием размера записываемых данных.\\
 +
 +**Физические** формируются уже на транспортном уровне, чаще всего для них отводится 65 536 байт (его размер хранится в двухбайтовом поле заголовка т.е. само это поле может содержать максимум такое значение), размер может меняться по согласованию сторон, содержится в TCP заголовках.\\
 +
 +Передача ведется потоковая, сначала идет служебная инфа, с указанием размера в т.ч., затем все остальное принимаем как содержимое файла, пока не достигнем указанный размер файла.\\
 +
 +Служебную инфу пишем с помощью датаСтрим, что бы был указан размер этого "программного" пакета, и чтобы нам вырезать точное кол-во байт, занимаемое этой служебной инфой, содержимое файла просто читаем пока не достигнем указанного размера.\\
 +
 +Cчитывание 4ех байт остается корректным до тех пор пока программный пакет < 4gb, т.к. в эти 4 байта умещено интовое значение, которое принимает максимум 4 млрд.. байтов ~ 4gb.\\
 +Если программный пакет будет больше, мы просто некорректно считаем значение его размера и следовательно сам пакет не сможем принять (будет '-1')\\
 +
 +<details>
 +<summary>:!: Пример: Сервер</summary>
 +
 +
 +sserv.h
 +<code cpp-qt>
 +
 +</code>
 +
 +sserv.cpp
 +<code cpp-qt>
 +
 +</code>
 +</details>
 +
 +
 +<details>
 +<summary>:!: Пример: Клиент</summary>
 +**Примечания:**\\
 +:?: Установка соединения (**connectToHost()**) проходит асинхронно, после ее вызова уже можно писать данные в сокет (**write()**), данные будут собираться в буфер (**неизвестно какое ограничение**), и будут ожидать записи.\\
 +Правда в случае ошибки соединения, буфер очистится, при проверке, данные были доступны вплоть до последнего сигнала об ошибке, при повторном запуске отправки, буфер уже был очищен.\\
 +:?: Запись можно делать из файла сразу в метод **write()**, без создания дополнительных **QByteArray** и **QDataStream**, как было в прошлых примерах.\\
 +**write()** принимает **QByteArray**, метод **read()** возвращает **QByteArray**, для записи служебных данных можно сделать отдельный метод для конвертации, вот тут та и понадобится **QDataStream**, который корректно запишет нужные данные в **QByteArray**.\\
 +:?: Что касается **проверки и установления** коннекта:\\
 +в нашем случае сокет может быть в след состояниях:\\
 +**0** - не подключен - нужно **вызвать коннект**\\
 +**1,2** - выполняет поиск и начал устанавливать соединение - соединения еще нет, но и делать вроде ничего не надо, правда неизвестно может ли оно быть зависшим в этот состоянии ?, думаю тут- **ничего не делать**\\
 +**3** - установленно - **ничего не делать**\\
 +**6** - вот вот закроется - т.е. запрошен дисконнект, ожидается отправка очереди данных и коннект захлопнется, в таком случае явно нужно снова **вызвать коннект**\\
 +
 +Что касается отправки файла, пишем данные кусками в метод **write()**, он возвращает кол-во записанных байт, это кол-во отнимаем от размера файла, так управляем циклом\\
 +В случае ошибки, **write()** возвращает **-1** и все идет по п#зде, поэтому необходимо проверять значение пред тем как с ним работать (отнимать от общем суммы)\\
 +Так же, после вызова **write()** и до фактической отправки данных нужно какое то время, до этого данные копятся в буфере (видно в **bytesToWrite()**), если писать в цикле то данные **не успевают** уходить в **заполняют буфер** до талого, поэтому нужен метод **wait()**, либо сигнало/слот можно прикрутить какой нибудь\\
 +
 +Данные **пишутся** так же **пакетами**, как были записаны в **write()**, по одному после каждого **wait()**\\
 +Если нет коннекта, данные не уходят, **bytesToWrite()** не очищается, последующие вызовы **write()** возвращают **-1**, **wait()** возвращает **false**\\
 +
 +
 +
 +sc.h
 +<code cpp-qt>
 +
 +</code>
 +
 +sc.cpp
 +<code cpp-qt>
 +
 +</code>
 +</details>
 +
 +
 +
 +
 +
 +
 +
  
  
develop/qt/network.1632898706.txt.gz · Последнее изменение: 2021/09/29 06:58 — admin