Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > udp с подтверждением доставки


Автор: JohnnyQ 30.3.2009, 18:21
Добрый день! 
Есть клиент-сервер на UDP. Нужно организовать подтверждение доставки.
отправка: 
Код

char buf[20000];
...
send( Socket, buf, 20000, 0 );
 
и прием
Код

recvfrom( LSocket, buf, sizeof(buf),0, (struct sockaddr *)&saclient, &saclient_length );

Хочу сделать, чтобы все отправляемые  пакеты нумеровались. Суть вопроса, номер пакета нужно отправлять в buf или есть способ передать номер пакета другим образом (можно ли передавать  не 
Код
 char buf[20000]; 
, а ,например, 
 структуру struct в которой будут храниться  
Код
 char buf[20000];  int n_packet
  ) 

Автор: SVN74 30.3.2009, 18:56
Цитата(JohnnyQ @  30.3.2009,  18:21 Найти цитируемый пост)
Суть вопроса, номер пакета нужно отправлять в buf 

да

Цитата(JohnnyQ @  30.3.2009,  18:21 Найти цитируемый пост)
можно ли передавать  не 
код C++
1:

 char buf[20000]; 




, а ,например, 
 структуру struct в которой будут храниться  
код C++
1:

 char buf[20000];  int n_packet

да
========
вместо send - надо sendto

Автор: vinick 30.3.2009, 19:32
Цитата(JohnnyQ @  30.3.2009,  18:21 Найти цитируемый пост)
char buf[20000];
...
send( Socket, buf, 20000, 0 );

ИМХО слишком большие датаграммы. Где-то я читал, что в реальности пакеты свыше 4кб большинством роутеров будут отброшены. Источник к сожалению не помню.

По сабжу - да можно.

Код

struct aaa
{
   char buf[10];
   int num;
};
...
aaa a;
...
send(fd,&a,sizeof(a));

только следи за порядком байт в номере

Автор: Anikmar 30.3.2009, 19:37
Цитата(vinick @  30.3.2009,  19:32 Найти цитируемый пост)
ИМХО слишком большие датаграммы. Где-то я читал, что в реальности пакеты свыше 4кб большинством роутеров будут отброшены. Источник к сожалению не помню.

Так в случае чего IP пакеты порежет как надо, а там соберет.

Автор: JohnnyQ 30.3.2009, 20:36
Цитата(vinick @ 30.3.2009,  19:32)
Цитата(JohnnyQ @  30.3.2009,  18:21 Найти цитируемый пост)
char buf[20000];
...
send( Socket, buf, 20000, 0 );

ИМХО слишком большие датаграммы. Где-то я читал, что в реальности пакеты свыше 4кб большинством роутеров будут отброшены. Источник к сожалению не помню.

По сабжу - да можно.

Код

struct aaa
{
   char buf[10];
   int num;
};
...
aaa a;
...
send(fd,&a,sizeof(a));

только следи за порядком байт в номере

ок! отправить мы можем, а принять данные как структуру реально??? 
например: 

Код

struct aaa
{
   char buf[10];
   int num;
};
...
aaa a;
...
recvfrom( LSocket, &a, sizeof(a),0, (struct sockaddr *)&saclient, &saclient_length );


Автор: SVN74 30.3.2009, 20:46
Цитата(JohnnyQ @  30.3.2009,  20:36 Найти цитируемый пост)
ок! отправить мы можем, а принять данные как структуру реально??? 

Да, создается не прерывный цикл до нужного заполнения (по размеру структуры) 

Автор: vinick 30.3.2009, 20:47
Цитата(JohnnyQ @  30.3.2009,  20:36 Найти цитируемый пост)
recvfrom( LSocket, &a, sizeof(a),0, (struct sockaddr *)&saclient, &saclient_length );

Да именно так, только помни про выравнивание и про порядок байт.


Цитата(Anikmar @  30.3.2009,  19:37 Найти цитируемый пост)

Так в случае чего IP пакеты порежет как надо, а там соберет. 

Если будет что собирать. Насколько я понял - для UDP фрагментация нежелательна.

Добавлено через 4 минуты и 51 секунду
Цитата(SVN74 @  30.3.2009,  20:46 Найти цитируемый пост)
Да, создается не прерывный цикл до нужного заполнения (по размеру структуры) 

Разве для UDP это имеет смысл?  smile 

Автор: SVN74 30.3.2009, 20:58
Цитата(vinick @  30.3.2009,  20:47 Найти цитируемый пост)
Разве для UDP это имеет смысл?    

Имеет, если надо отправлять маленькими пакетами ,а именно так и надо делать...

Автор: JohnnyQ 30.3.2009, 20:59
ок! всем спасибо!!! буду пробывать!!!

Автор: Anikmar 31.3.2009, 08:35
Цитата(vinick @  30.3.2009,  20:47 Найти цитируемый пост)
Если будет что собирать. Насколько я понял - для UDP фрагментация нежелательна.

По моему по барабану. UDP транспортный уровень и он ничего не знает о фрагментации собственно IP пакетов - это реализуется более низким IP протколом. Он будет фрагментировать как нужно для разных сегментов сети. И на качество собственно UDP это не должно отражаться - IP гарантирует сборку пакета UDP на приемнике в том виде, в каком он ушел с передатчика, если конечно он (пакет) до приемника дойдет. Если не все соберется - пакет просто будет отброшен.

Существуют, конечно, варианты, когда складываются неблагоприятные условия (например, пакет режется на две части, а во  второй только пара байт информации). Но ИМХО - жестко подгонять размер передаваемого блока достаточно хлопотно. Можно в протоколе предусмотреть увеличение/уменьшение кадра в зависимости от условий передачи. Мы заранее не знаем какой размер кадра у принимающей стороны будет и в промежуточных узлах. (Хотя это можно выяснить, конечно).

Я встречал в разных источниках разные рекомендации:
4 кб (достаточно устаревшая рекомендация на мой взгляд)
16 Кб (вроде как для большинства сетей оптимальна)
64 Кб (чаще всего встречал в последнее время. И кажется буфер виндовых сокетов именно такого размера по умолчанию, не проверял).

А вот дойдет собственно пакет UDP до получателя или нет - это уже никто не знает. И сколько времени он будет блуждать (возможно следующий пакет придет раньше предыдущего).

Другое дело при ненадежных каналах связи повторная отправка 64К все-таки более рессурсоемка. Поэтому от четких рекомендаций я воздержусь - слишком мало у меня опыта.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)