看计算机网络相关的书,每次看到IP或者UDP报头校验和时,都一瞥而过,以为相当简单。可是今天一看真傻眼了,怎么算的,为什么用反码不用补码还真不知道怎么回事。

算法的C语言实现:

unsignedshortcsum(unsignedchar *addr,intcount)

{

/* Compute Internet Checksum for "count" bytes

* beginning at location "addr".

*/

register long sum = 0;

while( count > 1 ) {

/* This is the inner loop */

sum += * (unsigned short) addr++;

count -= 2;

}

/* Add left-over byte, if any */

if( count > 0 )

sum += * (unsigned char *) addr;

/* Fold 32-bit sum to 16 bits */

while (sum>>16)

sum = (sum & 0xffff) + (sum >> 16);

checksum = ~sum;

return checksum;

}

计算校验和的算法思路:

1. 将原Checksum位置全部置0,把报头中每16bit作为一组,当成无符号数相加得到sum,若报头字节数为单数,则最后一个字节直接当8bit无符号数加到前面的sum上去。

2. 对sum右移16位,并与原sum的低16位相加,得到结果重新赋给sum。

3. 直到sum的高16位为0时,再将sum取反(反码),返回sum值作为Checksum。

接收端校验过程:

接收到的结果再进行一次上述计算,得到返回的值应该为0。否则,报头在传输过程中出错。

解释1:B + ~B = 2^16 - 1(B 为WORD),算法最后返回的是反码(反码求和又叫1的补码(one'scomplement),而2的补码就是我们通常说的补码求和了)。所以接收端收到数据报后得到的校验和为B + ~B(开始校验和占用的两个字节为0,现在更过发送端的校验后得到~B) = 2^16 - 1(B 为WORD),返回校验和的反码所以就检查校验和是否为0即可。

那么为什么用反码而不用补码呢?

a.不依赖系统是大端还是小端。即无论你是发送方计算或者接收方检查校验和时,都不需要调用htons 或者 ntohs,直接通过上面第2节的算法就可以得到正确的结果。这个问题你可以自己举个例子,用反码求和时,交换16位数的字节顺序,得到的结果相同,只是字节顺序相应地也交换了;而如果使用原码或者补码求和,得到的结果可能就不相同!比如补码计算:0xff02 + 0x00ff 和0x02ff + 0xff00结果是不相同的, 但是对于反码来说只是序列不同结果是相同的。

b.计算和验证校验和比较简单,快速。说实话,这个没怎么看明白,感觉在校验和计算方面,原码或者补码求和反而更简单一些(从C语言角度),在校验和验证上面,通过一样的算法判断结果是否为全0,确实要方便一些,所以可能从综合考虑确实反码求和要简便一些。另外,IP报文在传输过程中,路由器经常只修改TTL字段(减1),此时路由器转发该报文时可以直接增加它的校验和,而不需要对IP整个首部进行重新计算。

c语言 checksum,容易被忽视的IP报头中的Checksum校验和相关推荐

  1. 如何计算IP报头的checksum

    如果你研究过TCP/IP协议,那么你肯定知道IP报头中的checksum字段,或许你还曾经为如何计算这个字段的值所困扰,本文我们将讨论checksum的概念,并详细介绍IP报头中的checksum是如 ...

  2. 《深入浅出DPDK》读书笔记(十):硬件加速与功能卸载(VLAN、IEEE1588、IP TCP/UDP/SCTP checksum、Tunnel)

    Table of Contents 109.硬件卸载简介 110.网卡硬件卸载功能 111.DPDK软件接口 接收侧: 发送侧: 112.硬件与软件功能实现 113.VLAN硬件卸载 1. 收包时VL ...

  3. TCP/IP协议中分包与重组原理介绍、分片偏移量的计算方法、IPv4报文格式

    目录 一.什么是IP分片 二,为什么要进行IP分片 三.IP分片原理及分析 标志字段的作用 下面是标志位在IP首部中的格式以及各个标志的意义: TTL Protocol 协议号 分片包文示例: 分片偏 ...

  4. 已知子网掩码如何计算IP地址中的主机位

    原文链接:https://zhidao.baidu.com/question/214865175.html 某A类地址上的子网掩码是255.192.0.0,那么该IP地址中主机有多少位? 255.19 ...

  5. R语言使用basename函数获取数据链接地址中的文件名称(removes all of the path up to and including the last path separator )

    R语言使用basename函数获取数据链接地址中的文件名称(removes all of the path up to and including the last path separator (i ...

  6. R语言data.table导入数据实战:data.table中编写函数并使用SD数据对象

    R语言data.table导入数据实战:data.table中编写函数并使用SD数据对象 目录 R语言data.table导入数据实战:data.table中编写函数并使用SD数据对象 #data.t ...

  7. R语言ggplot2可视化:通过在element_text函数中设置ifelse判断条件自定义标签文本的显示格式:例如、粗体、斜体等

    R语言ggplot2可视化:通过在element_text函数中设置ifelse判断条件自定义标签文本的显示格式:例如.粗体.斜体等 目录

  8. R语言plotly可视化:plotly可视化在散点图中添加误差条(Scatterplot with Error Bars with plotly in R)

    R语言plotly可视化:plotly可视化在散点图中添加误差条(Scatterplot with Error Bars with plotly in R) 目录 R语言

  9. R语言可视化密度图并在密度图中嵌入图例信息、使用geomtextpath包的geom_textdensity函数,将图例(legend)信息嵌入到密度图中

    R语言可视化密度图并在密度图中嵌入图例信息.使用geomtextpath包的geom_textdensity函数,将图例(legend)信息嵌入到密度图中(Density plot with dire ...

最新文章

  1. 【带你玩转主题模型Topic Model】—— 之 利用sklearn 实现Latetnt Dirichlet Allocation(LDA)主题模型
  2. 拥抱iPhone,拥抱软件开发的未来
  3. python中内存管理机制一共分为多少层_python 内存管理机制
  4. 【自定义注解使用】增加service层方法访问日志
  5. DRF_APIView之认证、授权配置
  6. QT 4.8.5支持电容触摸屏 和 鼠标
  7. STL源码剖析 关联式容器 树 红黑树、二叉搜索树、平衡二叉搜索树
  8. TensorFlow 2.0 - tf.distribute 分布式训练
  9. (转载)python调用shell命令之os 、commands、subprocess
  10. Netty工作笔记0084---通过自定义协议解决粘包拆包问题2
  11. 夜上海音乐播放器 v 1.0
  12. pip和pip3 换源
  13. gif转换成jpg,这个方法很简单
  14. 使用Xcode创建第一个App
  15. @Resource详解
  16. 有个空间,名叫 Gamma
  17. ajax 更新局部视图,使用Ajax局部更新Razor页面的实例代码
  18. 汇智网mysql_MySQL 入门
  19. C++STL算法 search你是我的半截的诗
  20. 利用DOCX文档远程模板注入执行宏代码

热门文章

  1. 2013网络安全隐患多 安全防护要跟上
  2. IT 岗位说明书(岗位职责)
  3. 音视频 FFmpeg
  4. Error occurred during initialization of um Could not reserve enough space for object heap
  5. iOS架构设计:最初的MVC
  6. 两台电脑最简单的连接方法:直连
  7. 金蝶EAS,扩展报表,Java数据集代码示例
  8. 老板,我想请假去旅游!
  9. Echarts 做的温度计
  10. word排版技巧:如何让选择题多个选项快速对齐