我有兩個問題:關於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個最低有效位以外的任何數據。
謝謝!