一、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包在传输过程中是否出现错误。
