Zum Abrufen der MTU in Ihrer Schnittstelle, nicht für Path MTU Discovery, haben Sie struct ifreq. Eines seiner Felder ist ifr_mtu und dieses Feld liefert Ihnen die MTU. Sie lesen dieses Feld mit ioctl, SIOCGIFMTU für die richtige Schnittstelle. (http://man7.org/linux/man-pages/man7/netdevice.7.html)
struct ifreq {
char ifr_name[IFNAMSIZ]; /* Interface name */
union {
struct sockaddr ifr_addr;
struct sockaddr ifr_dstaddr;
struct sockaddr ifr_broadaddr;
struct sockaddr ifr_netmask;
struct sockaddr ifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
struct ifmap ifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char *ifr_data;
};
};
Beispiel:
#include <sys/socket.h>
#include <sys/types.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
int main(void)
{
int sock;
char *name = "enp0s3";
struct ifreq ifr;
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
printf("Creating socket: %d\n", errno);
exit(-1);
}
ifr.ifr_addr.sa_family = AF_INET;
strcpy(ifr.ifr_name, name);
if (ioctl(sock, SIOCGIFMTU, (caddr_t)&ifr) < 0) {
printf("Error ioctl: %d\n", errno);
exit(-2);
}
printf("MTU is %d.\n", ifr.ifr_mtu);
close(sock);
return 0;
}
Heute, in der Regel können Sie eine MTU von 1500 im Internet vertrauen, wenn Sie bestimmte Verbindungstechnologien wie Bluetooth oder Zigbee verwenden. Sie können Path MTU Discovery verwenden und Ihr UDP-basiertes Protokoll mit einem ACK implementieren, um zu überprüfen, ob die andere Seite die Nachricht erhalten hat. Jetzt ist die Implementierung eines ACK und Features des verbindungsorientierten Protokolls nicht dasselbe wie die Verwendung von TCP. Wenn Sie alles mit UDP machen können, ist es leichter als TCP.
Edit: Für die Verwendung von Path MTU Discovery, können Sie auch mit der Option IP_PMTUDISC_DO verwenden getsockopt:
IP_MTU_DISCOVER (since Linux 2.2)
Set or receive the Path MTU Discovery setting for a socket.
When enabled, Linux will perform Path MTU Discovery as defined
in RFC 1191 on SOCK_STREAM sockets. For non-SOCK_STREAM
sockets, IP_PMTUDISC_DO forces the don't-fragment flag to be
set on all outgoing packets. It is the user's responsibility
to packetize the data in MTU-sized chunks and to do the
retransmits if necessary. The kernel will reject (with
EMSGSIZE) datagrams that are bigger than the known path MTU.
IP_PMTUDISC_WANT will fragment a datagram if needed according
to the path MTU, or will set the don't-fragment flag
otherwise.
mehr Siehe hier: http://man7.org/linux/man-pages/man7/ip.7.html
Und warum Sie nicht empfehlen, die MTU während des Laufes zu bekommen -Zeit? – FrozenHeart
Weil Sie keine Garantie für den Pfad haben. Höchstwahrscheinlich wird sich dieser Pfad nicht ändern, aber es kann sein, und wenn sich der Pfad ändert, kann sich die MTU ändern. Wenn Sie sich darüber Sorgen machen, setzen Sie das DF-Bit und suchen Sie nach ICMP-Fehlernachrichten darüber. Die empfohlene UDP-Größe ist keine _my_ Empfehlung. Die beste Verwendung von UDP ist mit kleinen Datagrammen, so dass wenig verloren geht, wenn Pakete verloren gehen. Deshalb haben Sprache und Video mit UDP sehr kleine Datagramme. –
Auch Staus, dh Pakete fallen, _will_ ständig ändern, und es wird wahrscheinlich zu bestimmten Zeiten des Tages oder der Nacht schlechter sein. Wenn Sie eine hohe Toleranz für verlorene Daten haben, verwenden Sie eine größere Nutzlast, ansonsten halten Sie sie niedrig. –