我有两个问题:关于TCP校验和计算问题
RFC 793指出,校验应计算在一个96位的伪头,TCP报头和数据。伪首部包含源和目标IP地址。这不会破坏保持层单独的整体思路,因为现在当网络层开始使用不同大小的地址时,传输层也需要改变。
在另一个SO帖子中,我找到了下面的java代码来计算校验和。
private long computeChecksum(byte[] buf){ int length = buf.length; int i = 0; long sum = 0; long data; // loop through all 16-bit words unless there's 0 or 1 byte left. while(length > 1){ data = (((buf[i] << 8) & 0xFF00) | ((buf[i + 1]) & 0xFF)); sum += data; if((sum & 0xFFFF0000) > 0){ sum = sum & 0xFFFF; sum += 1; } i += 2; length -= 2; } if (length > 0){ // ie. there are 8 bits of data remaining. sum += (buf[i] << 8 & 0xFF00); // create a 16 bit word where the 8 lsb are 0's and add it to the sum. if((sum & 0xFFFF0000) > 0) { sum = sum & 0xFFFF; sum += 1; } } sum = ~sum; sum = sum & 0xFFFF; return sum; }
有一些事情我不明白为什么他们需要的代码。第一个在:
data = (((buf[i] << 8) & 0xFF00) | ((buf[i + 1]) & 0xFF));
什么是二进制AND的需要?我不明白,因为buf [i]是一个字节,但被视为一个int,并向左移8位。不是说已经保证结果如下所示:00000000 00000000 ???????? 00000000.
此外,为什么sum和data声明为long?就我所见,两个变量都不会超过17位,所以为什么不能使用int?最后他们甚至可以这样做:sum = sum & 0xFFFF它丢弃除16个最低有效位以外的任何数据。
谢谢!