0 / 0 / 0
Регистрация: 25.11.2015
Сообщений: 4
|
||||||||||||||||||||||||||
1 | ||||||||||||||||||||||||||
Функция recv не разблокируется после отправки сообщения в канал26.01.2016, 12:02. Показов 1529. Ответов 4
Метки нет (Все метки)
Добрый день уважаемые форумчане. В общем, возникла проблема связанная с передаче данных через сокеты. Написал я касс, в одном из методов которого создается 2 потока и затем в этих потоках создаются 2сокета, клиентский и серверный. Затем я реализовал 2 метода для приема и отправки сообщений между сокетами (функции recieveCMD и sendCMD). Вот как раз таки на данном этапе возникла проблема. Суть функция заключается в том, чтобы (передать/принять) через канал сначала длину сообщения, а затем уже само сообщение.
Например при удачном соединении клиента с сервером. сервер отправляет клиенту сообщение (sendCMD("HELLO")), клиент, соответственно, ждет сообщения от сервера (recieveCMD()). Сервер отправляет длину сообщения (4 байта), а клиент соответственно эти 4 байта считывает. Затем сервер отправляет уже само сообщение, но вот клиентский вызов recv() продолжает ожидать поступления в канал сообщения, хотя оно уже было отправлено. Как следствие поток клиента блокируется вызовом recv. Буду очень признателен, если вы поможете разобраться почему так происходит. Исходники: Заголовочный файл класса.
До этого момента все передается верно, проверил пошагово. И да, сокет используется блокирующий.
0
|
26.01.2016, 12:02 | |
Ответы с готовыми решениями:
4
Функция отправки сообщения работает неправильно Не закрывается окно после отправки сообщения Переадресация после отправки сообщения, PHP Переадресация на страницу после отправки сообщения |
Ушел с форума
|
|
26.01.2016, 12:10 | 2 |
Весь код не анализировал, но достаточно одного лишь фрагмента:
что в случае успеха будет прочитано от 1 до sizeof(buffer) байт. В данном случае размер буфера для recv - 4 байта, но прочесть она может за один вызов и три байта, и два, и один. Так что начать нужно с этого. Кстати говоря, это вообще наитипичнейшая ошибка всех, кто учит работу в сетях.
0
|
0 / 0 / 0
Регистрация: 25.11.2015
Сообщений: 4
|
|
26.01.2016, 12:29 [ТС] | 3 |
С этим согласен, но все же мне непонятно почему recv не реагирует на второй вызов send, ведь данные отправляются и что-то считаться должно, но такое ощущение что данные в канал не попадают.
Я даже пробовал отсылать сообщение по 1 байту, однако же результат прежний)) (recv не считывает ни 1 байта) Бьюсь над этим уже солидный кусок времени))) Хотя какое-то время назад я реализовывал похожую задачу на сокетах UNIX, так вот там таких проблем не возникало.
0
|
Ушел с форума
|
|
26.01.2016, 13:04 | 4 |
Сократи код до минимума и попробуй воспроизвести эту ситуацию.
То есть, без классов, без потоков и т.п., просто "голые" сокеты и больше ничего.
1
|
0 / 0 / 0
Регистрация: 25.11.2015
Сообщений: 4
|
|
26.01.2016, 14:31 [ТС] | 5 |
Сделал упрощенную программку без классов. И действительно проблемы исчезли и все сообщения корректно передаются.
Следовательно, моя организация классов как-то влияет на сокеты. Осталось разобраться что именно может повлиять на передачу сообщений в классе. Спасибо за то что, указали направление куда копать)) Добавлено через 59 минут Ну и конечно же решение в студию: Проблема оказалась простак как яйцо)) Для нормального обмена данными необходимо 3 сокета: первый - сокет сервера, который является "слушающим", он ждет пока к нему присоединится какой-нибудь клиент; второй - сокет сервера, на который он отсылает и с которого принимает данные от соединившегося с ним клиента ("рабочий" сокет); третий - сокет клиента, через который он обменивается данными с сервером. У меня в классе было всего 2 сокета и получилось так, что второй и третий сокеты представляли из себя 1 и тот же дескриптор)) А так как обмен данными происходит локально (клиент и сервер на 1 ПК в разных потоках), то данный сокет был "рабочим" для клиента. Для сервера же собственного "рабочего" сокета не было (он "перезатирался" клиентом). В результате чего данный сокет использовался и сервером и клиентом, что и приводило к зависанию вызова recv() с оной из сторон. Имхо это очень глупая ошибка с моей стороны, постарайтесь избегать таких ситуаций.
0
|
26.01.2016, 14:31 | |
26.01.2016, 14:31 | |
Помогаю со студенческими работами здесь
5
Вывод уведомления после отправки сообщения Вызвать метод после отправки сообщения клиенту Proforms Basik, пропадает капча после отправки сообщения Автоматический возврат на страницу после отправки сообщения с сайта Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |