自己做了一个计算TCP校验和的代码,参考了不少文档和别人的代码,把这个简单的功能实现了,可是我发现当我计算的包长度为偶数时将结果和原来数据报中的校验和比较是一致的,可当数据报长度为奇数时就怎么都不对。举例如下:
偶数时(一致的)
数据包
0000 45 00 00 28 06 32 40 00 80 06 49 27 3b 40 99 94 E..([email protected]';@..
0010 3b 40 9b 62 04 e0 0d 3d 89 0a b8 9c 67 12 4c ef ;@.b...=....g.L.
0020 50 10 ff ff fc 97 00 00                         P.......
计算TCP校验和的数据
0000 3b 40 99 94 3b 40 9b 62 00 06 00 14 04 e0 0d 3d ;@..;@.b.......=
0010 89 0a b8 9c 67 12 4c ef 50 10 ff ff 00 00 00 00 ....g.L.P.......
原始数据包中的校验和:fc97
计算得到的胶验和:fc97奇数时(有问题)
数据包
0000 45 00 00 4b 06 33 40 00 80 06 49 03 3b 40 99 94 [email protected].;@..
0010 3b 40 9b 62 04 e0 0d 3d 89 0a b8 9c 67 12 4c ef ;@.b...=....g.L.
0020 50 18 ff ff 7b 39 00 00 03 00 00 23 1e e0 00 00 P...{9.....#....
0030 00 00 00 43 6f 6f 6b 69 65 3a 20 6d 73 74 73 68 ...Cookie: mstsh
0040 61 73 68 3d 68 65 6c 6c 6f 0d 0a                ash=hello..
计算TCP校验和的数据
0000 3b 40 99 94 3b 40 9b 62 00 06 00 14 04 e0 0d 3d ;@..;@.b.......=
0010 89 0a b8 9c 67 12 4c ef 50 18 ff ff 00 00 00 00 ....g.L.P.......
0020 03 00 00 23 1e e0 00 00 00 00 00 43 6f 6f 6b 69 ...#.......Cooki
0030 65 3a 20 6d 73 74 73 68 61 73 68 3d 68 65 6c 6c e: mstshash=hell
0040 6f 0d 0a                                        o..
原始数据包中的校验和:7b39
计算得到的胶验和:7b5c请高手帮我看看是怎么回事啊,苦恼啊!

解决方案 »

  1.   

    我用到的方法与下面的代码类似
    USHORT checksum(USHORT *buffer, int size)
    {
        unsigned long cksum=0;    while (size > 1) {
            cksum += *buffer++;
            size  -= sizeof(USHORT);   
        }    if (size)
            cksum += *(UCHAR*)buffer;       cksum = (cksum >> 16) + (cksum & 0xffff);
        cksum += (cksum >>16);     return (USHORT)(~cksum); 
    }
      

  2.   

    WORD CPubFunction::Checksum(char *buf, int len)
    {
    WORD *pBuf = (WORD *)buf;
    int  size = len / 2;
    DWORD checksum = 0;
    int i = 0;
    for(i = 0; i < size; i++)
    {
    checksum += pBuf[i];
    }
    if(len % 2 == 1) checksum += (WORD)buf[len - 1];
    checksum = (checksum >> 16) + (checksum & 0xffff);
    checksum = (checksum >> 16) + (checksum & 0xffff);
    checksum = (~checksum) & 0xffff;
    return (WORD)checksum;
    }
      

  3.   

    checksum的计算方法是把包里面CHECKSUN那几位全部置0,然后再计算,再把算出的数值填进去.