2016-02-23 1 views
0

У меня есть приложения с 2 потоками. Первый поток (основной поток) и второй поток (tcp-client-thread). main-thread генерирует некоторые сообщения и помещает их в очередь для tcp-client-thread. tcp-client-thread должен отправить эти сообщения на сервер. Но, tcp-client-thread также должен получать сообщения от сервера.Отправка и получение данных с помощью tcp socket в одном потоке

Как я могу это сделать? recv останавливает текущую резьбу. Установите тайм-аут для recv? Затем после recv очередь проверки тайм-аута (от main-thread), а если есть сообщения, отправьте их, то никаких сообщений не начнется recv еще раз?

ответ

0

Если вы собираетесь использовать 2 потока, вы можете расширить до 3 потоков. Пусть функции отправки и получения находятся в отдельных потоках.

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

С другой стороны, принимает нить спит, пока не получит данные. Он добавляет данные в другую очередь, сообщает основной поток, что данные были получены и уходит спать.

Edit 1: Одна тема
Per заголовка, если вы хотите, чтобы выполнить ввод/вывод в одном потоке, вам нужно будет иметь цикл опроса (вы можете иметь ограниченное ожидание, но не рекомендуется).

Loop: 
    if (data received) then place data into input queue. 
    if (data in input queue) process some data (use small chunks). 
    if (data in output queue) send some data. 
end-loop. 

Идея состоит в том, чтобы блокировать блоки данных, чтобы предотвратить отсутствие входящих данных. Данные могут обрабатываться и выводиться, когда нет данных (и с несколькими итерациями). Это позволит решить большинство проблем синхронизации.

1

Вы можете делать свой ввод-вывод в одном потоке без вращения, но это намного сложнее, просто просто создавая другой поток, как это предлагается в другом ответе. Короче говоря, вам придется изменить свой код, чтобы обрабатывать ожидания нескольких типов событий одновременно, т. Е. Событие в сокете или на данных сигнализации о состоянии для отправки, например. В Windows вы должны использовать что-то вроде WSAEventSelect + WaitForMultipleObjects вместо select, а в Linux вы будете использовать что-то вроде eventfd с выбором. Обратите внимание, что при обработке сокета, если он блокируется, вы должны проверить доступность для чтения перед выпуском recv и проверить возможность записи перед отправкой, чтобы вы не блокировали одно или другое. Как я уже сказал, проще просто создать поток отправки ...

1

Необходимая вещь - это неблокирующий/асинхронный ввод-вывод. Вы должны прочитать некоторую теорию, прежде чем пытаться подделать любой код. Эта статья, например: http://www.wangafu.net/~nickm/libevent-book/01_intro.html

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