一、UDP校验和概述
UDP是面向无连接的协议,它不保证数据传输是否正确、有序、重复或者丢失。UDP包含一个16位校验和,可以用来检测传输过程中是否出现错误。
UDP校验和的计算方法主要是通过将UDP报文中所有16位的字数据都相加,然后将结果取反得到校验和。
#include <stdio.h> #include <stdlib.h> #include <string.h> unsigned short int check_sum(unsigned short int *addr,int len); int main() { unsigned short int buffer[1000]; int n; printf("Enter the number of words:"); scanf("%d",&n); printf("Enter %d words:n",n); for(int i=0;i 1) { sum += *addr++; len -= 2; } if(len==1) sum += *(unsigned char *)addr; sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return (unsigned short int)(~sum); }
二、校验和的计算过程
校验和计算过程包括数据的拆分、相加、溢出处理和取反运算。
数据的拆分
在计算校验和之前,需要将UDP报文中所有16位的字数据都相加。因此需要先将UDP报文按照16位拆分成若干个字数据,定义一个指向16位数据的指针,然后把UDP数据报的数据按照16位的单元进行拆分。
unsigned short int *addr; addr=(unsigned short int *)ip_head; sum=0; //初始和值为0 while(len>1){ sum+=*addr++; len-=2; }
相加
在拆分完UDP报文之后,接下来将每个16位的字数据相加。将每个16位数都加到一个32位的无符号整数中,以防止在数据相加时发生溢出。
while(len>1){ sum+=*addr++; len-=2; }
溢出处理
相加完成之后会有可能出现溢出,需要进行溢出处理。主要是将相加结果中高16位和低16位进行相加,如果高16位不为0,再将高16位和低16位进行相加,一直循环,直到高16位为0.
sum=(sum>>16)+(sum&0xffff); sum+=(sum>>16);
取反运算
计算完毕后,将结果取反,就得到了校验和的值。
return (unsigned short int)(~sum);
三、UDP校验和实例
下面是一个UDP数据包的实例,将其转化为16位字数据,使用上述计算方法可得到UDP的校验和。
//数据包 4500 003c 1c46 4000 8006 0000 c0a8 0001 c0a8 0002 0035 0000 0000 0000 0000 0000 0000 0000 0000 0000 //转化为16位字数据 0x4500 0x003c 0x1c46 0x4000 0x8006 0x0000 0xc0a8 0x0001 0xc0a8 0x0002 0x0035 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 //计算校验和 unsigned short int buffer[12] = {0x4500, 0x003c, 0x1c46, 0x4000, 0x8006, 0x0000, 0xc0a8, 0x0001, 0xc0a8, 0x0002, 0x0035, 0x0000}; unsigned short int udp_sum = check_sum(buffer, 12); //得到校验和值 0xbd16
四、总结
UDP校验和是通过将数据报中所有16位的字数据都相加,然后将结果取反得到校验和。在计算过程中,需要对数据进行拆分,相加,溢出处理和取反运算。校验和的作用在于检测UDP包在传输过程中是否出现错误。