gpt4 book ai didi

c++ - 了解 TCP 校验和函数

转载 作者:可可西里 更新时间:2023-11-01 02:44:55 24 4
gpt4 key购买 nike

我相信 TCP 校验和函数执行以下操作:

  1. 将伪报头和 TCP 段报头和数据分成 2 个字节的 block 。
  2. 如果最后一个 block 的长度不是 2 个字节,则在最后一个 block 的末尾添加一个 0 字节的填充,使其成为 2 个字节。
  3. 对和取反码得到 TCP 校验和。

听起来很简单。因此,我编写了自己的通用 checksum 函数:

#include <inttypes.h>
#include <arpa/inet.h>

uint16_t checksum(uint16_t * data, int size) {
uint16_t sum = 0;

int i = 0, length = size / 2;

while (i < length) sum += data[i++];

if (size % 2) sum += data[i] & 0xFF00;

return htons(~sum);
}

但是其他人编写的checksum 函数似乎更复杂。例如:

uint16_t checksum(uint16_t * addr, int len) {
int nleft = len;
int sum = 0;

uint16_t * w = addr;
uint16_t answer = 0;

while (nleft > 1) {
sum += *w++;
nleft -= sizeof(uint16_t);
}

if (nleft == 1) {
*(uint8_t *) (&answer) = *(uint8_t *) w;
sum += answer;
}

sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}

关于这段代码我有几个问题:

  1. 语句 *(uint8_t *) (&answer) = *(uint8_t *) w; 实际上做了什么?
  2. 为什么我们取总和为:

    sum = (sum >> 16) + (sum & 0xFFFF);
    sum += (sum >> 16);
  3. TCP checksum的计算方式有变化吗?

我真的不明白为什么我们做 sum = (sum >> 16) + (sum & 0xFFFF)。考虑 sum0xABCD:

0xABCD >> 16    == 0x0000

0xABCD & 0xFFFF == 0xABCD

0x0000 + 0xABCD == 0xABCD

这似乎是一个多余的步骤。下一条语句 sum += (sum >> 16) 也是如此。

最佳答案

What does the statement *(uint8_t *) (&answer) = *(uint8_t *) w; actually do?

这会将 uint16_t 转换为 uint8_t,因此只有 8 个最右边的位从 w 复制到 回答。考虑:

uint16_t x = 0x1234;
uint16_t* w = &x; // *w = // 0001001000110100

*(uint16_t *) (&answer) = *(uint16_t *) w; // answer = 0001001000110100

*(uint8_t *) (&answer) = *(uint8_t *) w; // answer = 0000000000110100

Why do we take the sum as:

sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
answer = ~sum;

32 位。 65536 ≡ 1 mod 65535,所以 end-around carry expression (sum & 0xffff) + (sum >> 16) 减少 sum65535。这是将任何(最终)结果进位添加回结果总和所必需的。

关于c++ - 了解 TCP 校验和函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22374040/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com