IP数据报首部校验和(长度是16位),用于检验首部的有效性和完整性。IP首部
校验和采用的是反码求和算法。就是把首部看成16位的整数序列。然后反码
求和。把得到的值放入首部校验和位置。反码求和算法如下:
0和0相加是0但要产生一个进位1,0和1相加是1,1和1相加是0.若最高位相加后产生进位,
则最后得到的结果要加1。
(0)反 + (0)反 = 1 + 1 = 10
(1)反 +(0)反 = 0 + 1 = 1
(1)反 + (1)反 = 0 + 0 = 0
在发送时,第一次发送前,首部校验和置0。然后用该算法算出校验和填充。接受端收到数
据后,用校验和算法(包含填充的检验和值)检验所有数据。结果应该为0。
#include "stdafx.h"
//16位反码求和算法
unsigned short checksum(unsigned short *buffer, int size)
{
unsigned long cksum = 0;
while(size>1)
{
cksum += *buffer++;
size -= sizeof(unsigned short);
}
if (size)
{
cksum += *(unsigned short*)buffer;
}
cksum = (cksum>>16) + (cksum&0xffff);
cksum += (cksum>>16);
return (unsigned short)(~cksum); //返回16位值
}
// 模拟数据
unsigned long cksum = 0;
while(size>1)
{
cksum += *buffer++;
size -= sizeof(unsigned short);
}
if (size)
{
cksum += *(unsigned short*)buffer;
}
cksum = (cksum>>16) + (cksum&0xffff);
cksum += (cksum>>16);
return (unsigned short)(~cksum); //返回16位值
}
// 模拟数据
struct datasum
{
char data[50];//数据
unsigned short checksum;//校验和
};
unsigned short checksum;//校验和
};
//测试程序
int _tmain(int argc, _TCHAR* argv[])
{
struct datasum msg = {"Hello World!",0};
msg.checksum=checksum((unsigned short*)&msg,sizeof(msg));
printf("checksum prev is: %d",msg.checksum);
msg.checksum=checksum((unsigned short*)&msg,sizeof(msg));
printf("checksum after is: %d",msg.checksum);
getchar();
return 0;
}
struct datasum msg = {"Hello World!",0};
msg.checksum=checksum((unsigned short*)&msg,sizeof(msg));
printf("checksum prev is: %d",msg.checksum);
msg.checksum=checksum((unsigned short*)&msg,sizeof(msg));
printf("checksum after is: %d",msg.checksum);
getchar();
return 0;
}