一、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协议。