您的位置:

UDP头部详解

一、UDP头部介绍

UDP(User Datagram Protocol)是一个提供无连接传输服务的协议,它被设计用于在IP网络上发送短消息。

UDP标准的头部长度为8个字节,由四个字段组成:源端口、目的端口、长度和检验和。

二、源端口和目的端口

源端口和目的端口是16位的整数,分别用于标识通信双方的端口号。

端口号的范围在0~65535之间,其中0~1023是保留端口号,1024~49151是注册端口号,49152~65535是短暂端口号。在UDP通信时,使用的端口号一般都是注册端口号。

struct udp_hdr {
    uint16_t src_port;      // 源端口
    uint16_t dst_port;      // 目的端口
    uint16_t length;        // UDP数据长度
    uint16_t checksum;      // UDP校验和
 } __attribute__((packed));

三、长度

UDP长度表示UDP报文中数据的长度,它包括UDP头部和应用数据部分的长度。UDP头部固定为8个字节,所以长度字段的值必须加上8后才能得到UDP报文的总长度。

注意,长度字段是一个16位的无符号整数,所以UDP报文的最大长度为65,535字节。

四、校验和

UDP校验和用于检测UDP报文传输中的错误,它是一种高效的检错手段。

校验和的计算方法是将UDP报文中8位一组的所有16位数进行二进制反码求和,然后对结果取反,得到的结果为校验和。

如果UDP报文传输过程中发生了改变,则接收方计算出的校验和与报文头部中的校验和不同,接收方必须将这个报文丢弃。

uint16_t in_cksum(uint16_t *addr, int len)
{
    int nleft = len;
    uint32_t sum = 0;
    uint16_t *w = addr;
    uint16_t answer = 0;

    while (nleft > 1) {
        sum += *w++;
        nleft -= 2;
    }

    if (nleft == 1) {
        *(unsigned char *)(&answer) = *(unsigned char *)w;
        sum += answer;
    }

    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    answer = ~sum;

    return answer;
}

五、UDP头部示例

下面是一个UDP头部的示例:

0                   1                   2                   3   
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Source Port Number        |     Destination Port Number   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            Length             |           Checksum            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             data                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

六、总结

UDP是一种用于提供无连接传输服务的协议,它提供了轻量级的、快速的数据传输服务。UDP头部由源端口、目的端口、长度和校验和四个字段组成,其中校验和是用于检测UDP报文传输中的错误,必不可少。我们需要了解UDP头部各个字段的定义和计算方法,才能更好地理解和使用UDP协议。