2015-01-16 2 views
2

Сокеты потока BSD имеют полный дуплекс, что означает, что две связанные стороны могут одновременно отправлять и получать.QTcpSocket действительно полный дуплекс?

QTcpSocket (реализация сокета qt) имеет асинхронную поддержку, неблокирующий режим, но может принадлежать только одному потоку, см. qt docs.

Объекты, управляемые событиями, могут использоваться только в одном потоке. В частности, это относится к механизму таймера и к сети .

Предположим, я хочу, чтобы поток tx и отдельный поток rx использовали один и тот же сокет и отправляли/принимали данные одновременно.

В моем понимании это может быть выполнено «через» сигналы/слоты qt, но нить сокета никогда не будет выполнять функции send() и receive() одновременно. Он просто запускает цикл событий, который будет делать это серийным образом и испускает сигналы при выполнении отправки/получения.

Да, мои потоки rx и tx могут работать одновременно и обрабатывать уведомления через слоты qt, но сам сокет никогда не используется в полнодуплексном режиме.

Правильно ли говорить, что: рассматривая только одну конечную точку, в потоке сокета, ее вызовы send() и receive() всегда последовательны, а не одновременно? (поскольку поток цикла события один нити только)

+0

«Скажем, я хочу, чтобы поток tx и отдельный поток rx использовали один и тот же сокет и отправляли/получали данные одновременно». Нет, не могу этого сделать. Все операции над данным сокетом * ДОЛЖНЫ * выполняться в том же потоке. Если вы попробуете то, что предложили, это приведет к отказу нескольких утверждений отладки Qt. Кроме того, чтобы поместить сокет в другой поток из 'QTcpServer', вам нужно подклассифицировать его и сделать небольшую обманку. –

+0

в моем примере есть три потока: резьба сокета, поток rx и поток tx. Socket thread запускает цикл событий и является единственным, выполняющим действительный send()/receive(). Потоки Rx и Tx просто управляют гнездом через сигналы/слоты или события. Это на 100% возможно. Мой вопрос о том, что действительно происходит в потоке сокета, где цикл событий действительно сериализует вызовы сокетов. – kcris

ответ

4

В моем понимании это может быть «сделано» с помощью Qt сигналов/слотов, но сокета поток никогда не будет действительно выполнить отправку() и получать() одновременно. Он просто запускает цикл событий, который будет делать это в серийном режиме и испускать сигналы при выполнении отправки/получения.

Правда, но имейте в виду, что ядро ​​буферов входящих и исходящих данных, а QTcpSocket устанавливает сокет неблокируемой, так что отправить() и RECV() вызовы всегда возвращают сразу и не блокировать событие -loop. Это означает, что фактические процессы отправки и получения данных будут происходить одновременно (внутри ядра), даже если (более или менее мгновенные) вызовы send() и recv() технически не работают. (*)

Да, мои приема и передачи потоков могут одновременно работать и обрабатывать уведомления через Qt слотов, но сам разъем действительно никогда не используется в режиме полного дуплекса. Это верно?

Это неверно. Потоки данных сокета могут (и делать) протекать в обоих направлениях по сети одновременно, поэтому сокет действительно является полнодуплексным. Полнодуплексная возможность присутствует независимо от того, используете ли вы один поток или несколько потоков.

(*) Вы можете протестировать это с помощью однопоточной программы Qt, которая использует QTCPSocket для отправки или получения данных, просто отключив кабель Ethernet вашего компьютера во время большой передачи данных. Если вызовы send() или recv() QTCPSocket блокируются до завершения, это блокирует поток GUI и заставляет ваш GUI перестать отвечать на запросы до тех пор, пока вы не подключите кабель (или пока соединение TCP не истечет через несколько минут).

Смежные вопросы