书上一直说,按二进制反码求这些16位字的和,取此和的二进制反码作为校验和。接收方按二进制反码求这些16位字的和,当无差错时结果应全为1,否则就是有差错出现,接收方应该丢弃这个数据报。
你不觉得没实践一下,感觉这个“定理”十分空虚???
下面是求校验和(还没取反之前)的程序:
#include <iostream>
using namespace std;
int main() {
char sum[18];
char a[18];
for (int i = 0; i < 16; ++i) {
sum[i] = '0';
}
// 循环加法
while (cin >> a) {
int last_step = 0;
for (int i = 15 ; i >= 0; --i) {
int sum_bit = sum[i] - '0';
int a_bit = a[i] - '0';
int result_bit = (sum_bit + a_bit + last_step) % 2;
if (sum_bit + a_bit + last_step >= 2) {
last_step = 1;
} else {
last_step = 0;
}
sum[i] = '0' + result_bit;
}
if (last_step == 1) {
for (int i = 15; i >= 0; --i) {
int sum_bit = sum[i] - '0';
int result_bit = (sum_bit + 1) % 2;
sum[i] = '0' + result_bit;
if (sum_bit + 1 >= 2) {
last_step = 1;
} else {
last_step = 0;
break;
}
}
}
}
cout << "case #" << endl;
for (int i = 0 ; i < 16; ++i) {
cout << sum[i];
if (i == 7) cout << " ";
}
cout << endl;
return 0;
}
初始化UDP数据报:
1001100100010011
0000100001101000
1010101100000011
0000111000001011
0000000000010001
0000000000001111
0000010000111111
0000000000001101
0000000000001111
0000000000000000
0101010001000101
0101001101010100
0100100101001110
0100011100000000
一开始,UDP校验和(还没取反)计算为:
10010110 11101101,发送方将其取反之后填入检验和字段:01101001 00010010
填入检验和字段后的UDP数据报:
1001100100010011
0000100001101000
1010101100000011
0000111000001011
0000000000010001
0000000000001111
0000010000111111
0000000000001101
0000000000001111
0110100100010010
0101010001000101
0101001101010100
0100100101001110
0100011100000000
接收方收到UDP数据报,对其求和(接收方这侧不需要求反码,算出来是什么就是什么):
结果全为1!说明了传输过程没有出现错误(实际上,你理解深一点,还是有可能出现错误的,只是一个错误掩盖了另一个错误的表象,意会一下)
现在假设传播过程中,某个比特位发生了变化,数据比特变为:
0001100100010011
0000100001101000
1010101100000011
0000111000001011
0000000000010001
0000000000001111
0000010000111111
0000000000001101
0000000000001111
0110100100010010
0101010001000101
0101001101010100
0100100101001110
0100011100000000
不全为1!传输中出现差错。
以上!