这两天在做个接收海量数据的项目,服务端接收处理客户端发送上来的数据。本来没什么可以多说的,但中间出了个有趣的插曲,让我折腾半天不管怎么调就是不对。原来是一有个性的哥们在做数据校验和时,出于自己的兴趣爱好更改协议中约定的校验值计算方法,用了他常用或偏爱的那种方法。本来想让他修改的,可出于升级工作和服务端刚建设的综合考虑,最后还是采取了服务端更改检验和计算方式的做法。为纪念为之付出艰辛调试的几个小时,在此立字铭记。
C++计算CheckSum的方法:
unsigned short CAoe::CheckSum(unsigned short *buffer, int size)
{
unsigned long cksum=0;
while( size>1 )
{
cksum+=*buffer++;
size-=sizeof(unsigned short);
}
if( size )
{
cksum+=*(unsigned char *)buffer;
}
while (cksum>>16)
{
cksum=(cksum>>16)+(cksum & 0xffff);
}
return (unsigned short) (~cksum);
}
Java计算CheckSum的方法:
public char checkSum(byte[] buf, int size) {
long ckSum = 0;
for (int i = 0; i < size - 1; i += 2) {
ckSum += (((buf[i + 1] << 8) & 0xff00) ^ (buf[i] & 0xff));
}
if (size % 2 == 1) {
ckSum += buf[size - 1] & 0xff;
}
ckSum = (ckSum >> 16) + (ckSum & 0xffff);
ckSum += (ckSum >> 16);
return (char) (~ckSum);
}