Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Прием данных через recvfrom, Можно ли делать повторный вызов функции? 
:(
    Опции темы
mephistotel77
Дата 16.4.2010, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 12.4.2010

Репутация: нет
Всего: нет



У меня возник такой вопрос:
Я отсылаю команду серверу (железке), в ответ (как я понял это шесть байт, 4*байт + 1*int16_t) она присылает мне свое состояние в соответствии с протоколом). Но нужно точно знать, что я правильно понял спецификацию и что протокол не изменен. Т.е. что мне передаются именно 6 байт и я именно их и считываю.
Код

...
const uint32_t sizebuff = 65535 - (20 + 8);
uchar *buff = (uchar *) malloc(sizebuff);
bzero(buff, (size_t) sizebuff);
...
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
...
int size = sendto(sockfd, command, sizeof(command), 0, (sockaddr) &servaddr, sizeof(servaddr));
if (size == -1)
{
   ...
}
else
{
   int size = recvfrom(sockfd, buff, sizeof(buff), 0, (sockaddr) &inputaddr);
}

Интересуют подходы к тому как можно считать эти самые 6 байт, при этом чтобы гарантированно знать что ещё каких-то данных в сокете не осталось:
1. Попытаться считать количество байт данных, максимальное для протокола UDP и recvfrom возратит количество реальные данных.
Код

int size = recvfrom(sockfd, buff, sizeof(buff), 0, (sockaddr) &inputaddr);
if (size == 6)
{
  //Все хорошо
}

2. Я считываю ровно 6 байт и потом смотрю, а остались ли в сокете ещё какие-то данные?
Код

uint i = 0;
while (recvfrom(sockfd, buff, 6, 0, (sockaddr) &inputaddr) != 0)
{
  i++;
  if (i > 1)
 {
   perror(recvfrom); // Ошибка. Значит данные организованы по другому
   break;
 }
 //Считываем пока есть данные
}

либо вариации на эту тему (кстати более оптимальный/правильный/кошерный код приветствуется).
Можно ли сделать как во втором случае?
Стивенс пишет по этому поводу (Unix. Разработка сетевых приложений, 3 издание, стр. 278)
"Для сокета на уровне UDP происходит неявная буферизация дейтаграмм в виде очереди. Действительно у каждого сокета UDP имеется буфер приема, и каждая дейтаграмма, приходящая на этот сокет, помещается в его буфер приема. Когда процесс вызывает функцию recvfrom, очередная дейтаграмма из буфера возвращается процессу в порядке FIFO..."
Т.е. если я считал 6 байт из 10 байт дейтаграммы и вызвал опять recvfrom, то я считаю оставшиеся 4 байта или получу данные с другой дейтаграммы?

PM MAIL   Вверх
MAKCim
Дата 17.4.2010, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Цитата(mephistotel77 @  16.4.2010,  16:43 Найти цитируемый пост)
Т.е. если я считал 6 байт из 10 байт дейтаграммы и вызвал опять recvfrom, то я считаю оставшиеся 4 байта или получу данные с другой дейтаграммы?

нет
будет установлен MSG_TRUNC и 4 байта будут потеряны

в вашем случае нужно считывать PMTU - 20 - 8 байт (максимальный размер UDP сообщения) по сути первый случай


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
sigizmynd
Дата 13.8.2010, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 13.8.2010

Репутация: нет
Всего: нет



короче,смотри,
в функцие recvfrom есть поле флаги
он имеет 3 различных флага
я думаю, что в данном случае для тебя будет интересен флаг MSG_WAITALL
привожу описание из книги Рочкинда "программирование для Unix"
MSG_WAITALL используется только для сокетов с установленным соединением.
блокирует recvfrom до тех пор пока не будет получено запрошенное число байт, флаг MSG_PEEK сброшен вызов не был прерван сигналом....
единственный минус этого флага, что он работает только с TCP(((

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0631 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.