1 / 1 / 1
Регистрация: 29.08.2015
Сообщений: 40
1

Пропадает сообщение из сокета

15.02.2016, 19:56. Показов 1109. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день
Столкнулся с одной проблемой, нет сообщений в сокете, а сервер судя по логам их посылал.
Обрабатываю следующим кодом:
C++
1
2
3
4
5
6
7
8
9
10
11
ssize_t bytes_recieved = 11;// какое-нибудь число и цикл пока не равно -1, нет новых сообщений в сокете
    char incoming_data_buffer[1000];
    while (bytes_recieved>0) {
        
        incoming_data_buffer[0] = 0;
        bytes_recieved = recv(sock, incoming_data_buffer, 1000, MSG_DONTWAIT);// 0);//MSG_DONTWAIT
        if (bytes_recieved == 0){
            std::cout << "host shut down." << std::endl ;
        }
        if (bytes_recieved > 8) {
//дальше обработка и ковычки }}
Вызываю эту функцию в цикле, в нем есть и другие действия, так что возможна задержка
Есть у кого-нибудь предположения или советы? Заранее благодарен
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.02.2016, 19:56
Ответы с готовыми решениями:

Копирование сокета или передача сокета в функцию
Добрый день всем, столкнулся с тем что не могу скопировать сокет. boost::asio::ip::tcp::socket...

Как получить IPAddress сокета, отправившего сообщение
Добрый вечер, работаю над клиент-серверным приложением. И столкнулась с такой проблемой, мне нужно...

Выкидывает из аськи, пропадает соединение со стимом, полностью пропадает инет
У меня проблемка такая с соеденением к интернету, не знаю что делать... Вообщем комп работает...

Пропадает общий доступ, когда пропадает интернет
На нашем предприятии локальная сеть, имеющая организацию &quot;рабочая группа&quot;. В кабинете используется...

7
-L
15 / 9 / 12
Регистрация: 03.12.2015
Сообщений: 79
15.02.2016, 23:04 2
При выставке флага MSG_DONTWAIT операция проводится в неблокирующем режиме. Если операция не может быть завершена немедленно (например, нет данных) будет возвращено значение -1 в bytes_recieved и будет осуществлён выход из цикла. Так и происходит? Что показывает errno?
0
1 / 1 / 1
Регистрация: 29.08.2015
Сообщений: 40
16.02.2016, 10:33  [ТС] 3
-L в коде я написал часть метода, который вызывается в другой части программы и вызывается он в цикле. Этот метод должен вычитывать все сообщения из сокета, что он и делает, жаль, что пару сообщений не читает

Добавлено через 22 минуты
-L так и происходит, ошибку прога не принтует, попробую подключить errno.h, но раньше этого не делал
0
-L
15 / 9 / 12
Регистрация: 03.12.2015
Сообщений: 79
16.02.2016, 13:23 4
Shakior, если представленный кусок кода вызывается во внешнем цикле, то по идее несмотря на неблокирующий режим всё должно читаться. Вы говорите, что только пару сообщений не читает. Эти сообщения в начале передачи? Умещаются в размер incoming_data_buffer? Протокол TCP? Если будете пользовать errno, то надо смотреть любые кроме EAGAIN и EWOULDBLOCK.
0
1 / 1 / 1
Регистрация: 29.08.2015
Сообщений: 40
16.02.2016, 14:29  [ТС] 5
Да, сообщения в начале передачи, но уже после того, как некоторые пришли(подтверждение соединения и авторизации - они приходят, раз 10 этот метод вызывается до не приходящего сообщения). Сообщения максимум 200 байтов, так что помещается. Протокол TCP. Была такая же проблема, ее исправило то, что я в этот метод добавил цикл, в котором считываю все сообщения, до этого 1 вызов метода считывал одно сообщение, и сообщения куда-то пропадали. Есть предположения куда могут сообщения из сокета и почему пропадать? Полагаю, что вызов в цикле этого метода в отдельном потоке исправит ситуацию. Но причины интересны
0
-L
15 / 9 / 12
Регистрация: 03.12.2015
Сообщений: 79
16.02.2016, 15:22 6
Лучший ответ Сообщение было отмечено Shakior как решение

Решение

Shakior, не уверен, что отдельный поток поможет, так как кажется мне, что дело здесь не в периоде работы цикла. К сожалению, у меня не достаточно знаний, чтобы сходу сказать, в чём проблема. Но TCP гарантирует передачу сообщений, и даже если было отправлено несколько до того, как Вы успели их прочитать, они всё равно должны быть доступны для чтения, когда очередь наконец дойдёт до recv, так как по сути это просто поток байт. У вас должен быть предусмотрен механизм извлечения нужного сообщения из этой последовательности. Читающий сокет ничего не знает о том, какой длины Вы передали сообщение, он знает только, что ему нельзя читать больше 1000 байт (в приведённом коде). Возможно Вам следует передавать длину сообщения (или завершающий символ), чтобы распределять их между обработчиками и знать, сколько нужно скопировать из incoming_data_buffer (если Вы так уже не делаете). В противном случае может получится какая-нибудь каша на выходе. Просто я вижу, что обработка происходит, если прочитано байт больше 8 ,что возможно не совсем верно. Так как если пришло сообщение 12 байт, а потом 40 байт, то в сокете лежат уже два сообщения. А читающий код просто увидит, что доступно 52 байта и попытается их вытащить за раз и отправить на обработку. Возможно это у Вас уже предусмотрено.

Также можно попробовать проверить ещё раз отправку на стороне сервера. К сожалению, больше видимо ничем помочь не смогу =(
1
1 / 1 / 1
Регистрация: 29.08.2015
Сообщений: 40
17.02.2016, 13:07  [ТС] 7
Вы и так очень помогли, спасибо. Буду проверять длину сообщения, тк предполагаю, что в сокете 2 сообщения лежат сразу.

Добавлено через 22 минуты
Действительно, 2 сообщения считывал сразу, а накладывал на структуру только одно. Еще раз, спасибо.
0
-L
15 / 9 / 12
Регистрация: 03.12.2015
Сообщений: 79
17.02.2016, 14:27 8
Shakior,
0
17.02.2016, 14:27
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.02.2016, 14:27
Помогаю со студенческими работами здесь

Периодически пропадает USB и пропадает курсор мыши
Добрый день Не так давно установил Виндоус 8. Периодически появляется проблема, вероятно,...

Чтение из сокета
Здравствуйте! Подскажите, как сделать, чтоб попытка чтения данных из разорванного сокета приводила...

Замена сокета
Здравствуйте, имеется такая проблема. Мой друг обратился с жалобой то что компьютер перестал...

Уничтожение сокета
connect(client, SIGNAL(disconnected()), client, SLOT(deleteLater())); эта команда, на сервере,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru