Pensamiento basado en la longitud máxima del datagrama UDP y el valor MTU

Longitud máxima del datagrama UDP

   En teoría, la longitud máxima de un datagrama IP es de 65535 bytes, que está limitada por el campo de longitud total de 16 bits en el encabezado IP (Figura Formato de protocolo IP). Elimine el encabezado IP de 20 bytes (formato de protocolo de figura IP) y el encabezado UDP de 8 bytes (formato de protocolo de figura UDP). La longitud máxima del usuario en el datagrama UDP es 65507. Sin embargo, la mayoría de las implementaciones proporcionan una longitud mayor que El valor máximo es pequeño.

   

   

     Encontraremos dos factores limitantes.

      Primero, la aplicación puede estar restringida por su interfaz de programa. La API de socket proporciona una función que las aplicaciones pueden llamar para establecer la longitud de las memorias intermedias de recepción y envío. Para los sockets UDP, esta longitud está directamente relacionada con la longitud del datagrama UDP más grande que la aplicación puede leer y escribir. La mayoría de los sistemas ahora proporcionan sus propios datagramas UDP que pueden leer y escribir más de 8192 por defecto.

      La segunda limitación proviene de la implementación del núcleo de TCP / IP. Puede haber algunas características de implementación (o errores) que hacen que la longitud del datagrama IP sea inferior a 65535 bytes.

      Pruebe el código de longitud máxima del datagrama udp

      servidor.c

      

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys / socket.h >
#include <netinet / in.h>
#include <sys / types.h>
#include <arpa / inet.h>

#define SERVER_PORT 8888
#define MAX_MSG_SIZE 1024

void udps_respon (int sockfd)
{
    struct sockaddr_in addr;
    int addrlen, n;
    char msg [MAX_MSG_SIZE];
    
    while (1) {
        / * lee desde la red y escribe en la red * /
        bzero (msg, sizeof (msg)) ; // Inicializar, establecer 0
        addrlen = sizeof (struct sockaddr);
        n = recvfrom (sockfd, msg, MAX_MSG_SIZE, 0, (struct sockaddr *) & addr, & addrlen); // Recibir datos del cliente
        msg [n] = ' \ 0 ';
        / * Mostrar que el servidor ha recibido el mensaje * /
        fprintf (stdout, "El servidor ha recibido% s", msg); // Mostrar el mensaje
    } 
}

int main (int argc, char * argv [])
{
    int sockfd;
    struct sockaddr_in addr;
    
    / * 建立 sockfd 描述 符 * /
        sockfd = socket (AF_INET, SOCK_DGRAM, 0);
        if (sockfd <0) {
                fprintf (stderr, "Error de socket:% s \ n", strerror (errno));
                salida (1);
        }

    / * Estructura de
    sockaddr llena del lado del servidor * / bzero (& addr, sizeof (struct sockaddr_in));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl (INADDR_ANY);
    addr.sin_port = htons (SERVER_PORT);
    
    / * Sockf Descriptor * /
    if (bind (sockfd, (struct sockaddr *) & addr, sizeof (struct sockaddr_in)) <0) {
        fprintf (stderr, "Error de enlace:% s \ n", strerror (errno));
        salida (1 );
    }
    printf ("udp server start ...... \ n");
    udps_respon (sockfd); // Operaciones de lectura y escritura
    close (sockfd);
}
 

cliente.c

   

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys / socket.h >
#include <netinet / in.h>
#include <sys / types.h>
#include <arpa / inet.h>

#define SERVER_PORT 8888
#define MAX_BUF_SIZE 65508

void udpc_requ (int sockfd, const struct sockaddr_in * addr, int len)
{
    char buffer [MAX_BUF_SIZE + 1];
    int n;
    int i = 0;
    // while (1) {
        / * 从 键盘 读 入 , 写到 服务器 * /
        printf ("Ingrese char: \ n");
        memset (buffer, 0, sizeof (buffer));
        // fgets (buffer, MAX_BUF_SIZE, stdin);
        para (i = 0; i <MAX_BUF_SIZE; i ++)
        {
            buffer [i] = 'a';
        }
        n = sendto (sockfd, buffer, strlen (buffer), 0, (struct sockaddr *) addr, len);
        // bzero (buffer, MAX_BUF_SIZE);
        printf ("enviar bytes:% d \ n", n);
    //}
}

int main (int argc, char * argv [])
{
    int sockfd;
    struct sockaddr_in addr;
    
    if (argc! = 2) {
        fprintf (stderr, "Uso:% s server_ip \ n", argv [0]);
        salida (1);
    }
    
    / * 建立 sockfd 描述 符 * /
    sockfd = socket (AF_INET, SOCK_DGRAM, 0);
    if (sockfd <0) {
        fprintf (stderr, "Error de socket:% s \ n", strerror (errno));
        salida (1);
    }

    / * Rellene los datos del servidor * /
    bzero (& addr, sizeof (struct sockaddr_in)); // Inicialice, establezca 0
    addr.sin_family = AF_INET;
    addr.sin_port = htons (SERVER_PORT);
    if (inet_aton (argv [1], & addr .sin_addr) <0) {/ * la función inet_aton se usa para convertir la dirección IP de tipo de cadena a la dirección IP de tipo de red * /
        fprintf (stderr, "Error Ip:% s \ n", strerror (errno));
        salir ( 1);
    }
    
    udpc_requ (sockfd, & addr, sizeof (struct sockaddr_in)); // Operaciones de lectura y escritura
    close (sockfd);
}
 

HUMANO 值

    Consulte TCP / IP para obtener una explicación detallada del Volumen I, Experimentos globales de Internet

     Como experimento, ejecutamos el programa de traceroute modificado muchas veces. El destino es alojar en todo el mundo, que puede llegar a 15 países (incluida la Antártida), utilizando múltiples enlaces transatlánticos y transpacíficos. Sin embargo, antes de hacerlo, el MTU de enlace SLIP de acceso telefónico entre la subred del autor y el enrutador netb se aumentó a 1500, que es lo mismo que Ethernet.

    Entre las 18 carreras, solo dos de ellas encontraron que la ruta MTU era inferior a 1500. Uno de los enlaces transatlánticos tiene un valor MTU de 572, y el enrutador devuelve un nuevo mensaje de error de formato ICMP. El otro enlace, entre dos enrutadores en Japón, no puede procesar marcos de datos de 1500 bytes, y el enrutador no devuelve mensajes de error ICMP en el nuevo formato. Establezca el valor de MTU en 1006 para que funcione normalmente.

      De este experimento, podemos leer la conclusión de que muchas, pero no todas, las WAN ahora pueden manejar paquetes de más de 512. Usando el mecanismo de descubrimiento de MTU de ruta, las aplicaciones pueden hacer un uso completo de la MTU más grande para enviar paquetes.

     Para el valor MTU, el host debe poder recibir al menos 576 bytes de datagramas IP. En muchos diseños de aplicaciones UDP, los datos de la aplicación están limitados a 512 bytes o menos, por lo que son más pequeños que este valor límite. Por supuesto, siempre podemos enviar menos de 512 bytes de datos analizando muchos protocolos de enrutamiento (DNS TFTP BOOTP SNMP).

   

 

 

         

78 artículos originales publicados · 32 elogiados · 120,000 visitas

Supongo que te gusta

Origin blog.csdn.net/caofengtao1314/article/details/99713270
Recomendado
Clasificación