- Можно ли вызывать send () для одного и того же сокета из нескольких потоков?
(при условии, что в пакете будет информация
заголовок о том, какой поток отправителя (т.е.
подсистема) принадлежит).
Конечно, вы можете вызывать его из нескольких потоков. Но помните, что вы должны поставить блокировку на сокете, чтобы синхронизировать это. В противном случае вы можете получить информацию, написанную противоречиво.
- Наличие одного блокирующего сокета на принимающей стороне, вызов recv () в цикле
из одних ниток, как "раскошелиться"
полученные пакеты разных
логические потоки к другому работнику
темы?
Как насчет написания BeginRecv и EndRecv, аналогичных boost asios library (или переходу на Boost Asio. Он не зависит от платформы!). Когда вы получили полное сообщение, вы можете отправить его. Я полагаю, вы хотели бы поместить это куда-нибудь еще, чтобы продолжить получать из сети? Вы можете просто использовать CreateThread и отправить ваши данные через параметр lpParameter
, и это будет проблемой кого-то другого, чем recv. Не будет особого смысла в разветвлении этого до загрузки ваших данных, потому что вам все равно нужно загрузить полный пакет, прежде чем сможет быть следующий.
- Какими были бы ваши дополнительные рекомендации для реализации
многопотоковая передача через один
порт
Не знаю много об этом, но я написал ответ ранее относительно Winsock, где я описываю, насколько неопределенным является recv (). Не забудьте выполнить синхронизацию, чтобы убедиться, что один пакет записан до того, как следующий будет.
Когда вы говорите «заблокировать сокет», вы
означает сериализовать доступ к send ()
функционировать? например с критическим разделом?
Да, действительно. Вы можете сделать это довольно используя, например, RAII для блокировки (тогда она будет автоматически удалена / разблокирована при возврате функции). Но да, используйте функцию sendData
, в которой вы сначала блокируете объект, а затем отправляете свои данные.
Теперь вот вопрос - как их пройти.
Ну, вы можете просто передать его как новый поток.
DWORD WINAPI myVideoProcessor(LPVOID theData){
StructForKeepingVideoData* data = dynamic_cast<StructForKeepingVideoData*>(theData);
// process the data that is passed in theData
...
}
...
void ReceiveData(){
while (true){
...
char buffer[SIZE];
recv(mySocket, buffer, SIZE, 0);
StructForKeepingVideoData* data = new StructForKeepingVideoData(buffer);
HANDLE mId = CreateThread(NULL, 0, myVideoProcessor, data, 0, NULL);
// now, the video processing will be done somewhere else. let's continue receiving data!
}
}
Я немного смутный здесь .. Но я думаю, что вам следует проверять наличие таких конструкций, как auto_ptr или shared_ptr при передаче данных - это поможет вам уничтожить данные.
Единственный способ, о котором я подумал, это
Объекты события: SetEvent () из
поток приемника для запуска
WaitForSingleObject () (который находится в
какая-то петля) в разных темах. Можно
ваш совет, если это приемлемо
решение?
События бы тоже сработали, но я не рискнул. Тогда вы просто будете постоянно поддерживать поток, а не запускаться, когда у вас есть данные для обработки.
Помните , что вам также необходимо поддерживать синхронизацию передачи данных. Если у вас есть какая-то очередь в очереди, вы должны убедиться, что запись и чтение выполняются одна за другой.
Можете ли вы предложить что-нибудь
лучше? Не там быстрее
решения для этого («триггер»
другая нить того же
приложение) чем объекты событий? А также
как передать данные?
Не знал бы ничего быстрее. Но чтобы передать данные, сделайте это при создании потока или используйте какую-то очередь, которую вы синхронизируете.
Надеюсь, это поможет.