У меня есть классы C ++, которые обрабатывают отправку и получение пакетов UDP.До сих пор я использовал их для отправки сигналов (PING, WAKEUP, ...) другими словами, очень маленьких пакетов и никогда не было проблем.
Теперь я хотел бы отправить большиеблоки данных (то есть 0,5 Мб), но чтобы оптимизировать возможность потери пакетов, я хочу иметь возможность выполнять свою собственную фрагментацию.Сначала я написал функцию, которая дает мне размер MTU:
int udp_server::get_mtu_size() const
{
if(f_mtu_size == 0)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));
if(ioctl(f_socket, SIOCGIFMTU, &ifr) == 0)
{
f_mtu_size = ifr.ifr_mtu;
}
else
{
f_mtu_size = -1;
}
}
return f_mtu_size;
}
Примечание: я знаю о PMTUD, который эта функция игнорирует.Как упомянуто ниже, это должно работать в управляемой сети, поэтому путь MTU не только изменится у нас.
Эта функция может вернуть 1500 в Linux.
Чтона самом деле неясно и кажется противоречивым во многих ответах, что этот размер в 1500 байт был бы не только моей полезной нагрузкой.Возможно, он будет включать некоторые заголовки, над которыми у меня нет контроля (например, заголовок Ethernet + нижний колонтитул, заголовок IPv4, заголовок UDP).
Из некоторых других вопросов и ответов создается ощущение, что я могу отправить 1500 байт данных безфрагментация, при условии, что все мои MTU равны 1500.
Итак ... Что верно?
Мой буфер данных может иметь размер, равный MTU
Мой буфер данных должен быть MTU - sizeof(various-headers/footers)
PS Сеть - это сеть, которую мы контролируем на 100%.Пакеты будут передаваться с одного главного компьютера на набор подчиненных компьютеров с использованием многоадресной передачи UDP.Между ними есть только один коммутатор 1 Гбит / с.Ничего больше.