首先介绍一下1的补码,2的补码:(摘自http://blog.csdn.net/cradmin/article/details/3092559

过1的补码,2的补码,到网上搜了下找到这个:

It is the 1’s complement of the 1’s complement sum of all the 16-bit words in the TCP header and data       这是关于TCP头部校验和字段(checksum field)的说明。
补码:补码是计算机中二进制数表达负数的办法,这样可以在计算机中把两个数的减法变成加法。补码形式有1的补码和2的补码,其中1的补码用在IP、TCP的校验和中;
The checksum algorithm is simply to add up all the 16-bit words in one's complement and then to take the one's complement of the sum.
1's Complement Arithmetic
The Formula
~N = (2^n -1) - N
where: n is the number of bits per word
N is a positive integer
~N is -N in 1's complement notation
For example with an 8-bit word and N = 6, we have:
~N = (2^8 -1) - 6 = 255 - 6 = 249 = 11111001

In Binary
An alternate way to find the 1's complement is to simply
take the bit by bit complement of the binary number.
For example: N = +6 = 00000110
N = -6 = 11111001
Conversely, given the 1's complement we can find the
magnitude of the number by taking it's 1's complement.
The largest number that can be represented in 8-bit 1's
complement is 01111111 = 127 = 0x7F. The smallest is
10000000 = -127. Note that the values 00000000 and
11111111 both represent zero.
Addition
End-around Carry. When the addition of two values
results in a carry, the carry bit is added to the sum in the
rightmost position. There is no overflow as long as the
magnitude of the result is not greater than 2^n-1.
2's Complement Arithmetic
The Formula
N* = 2^n - N
where: n is the number of bits per word
N is a positive integer
N* is -N in 2's complement notation
For example with an 8-bit word and N = 6, we have:
N* = 2^8 - 6 = 256 - 6 = 250 = 11111010

In Binary
An alternate way to find the 2's complement is to start at
the right and complement each bit to the left of the first
"1".
For example: N = +6 = 00000110
N* = -6 = 11111010
Conversely, given the 2's complement we can find the
magnitude of the number by taking it's 2's complement.
The largest number that can be represented in 8-bit 2s
complement is 01111111 = 127. The smallest is
10000000 = -128.
Addition
When the addition of two values results in a carry, the
carry bit is ignored. There is no overflow as long as the
is not greater than 2^n-1 nor less than -2^n.

我们之前学的是2的补码:正数补码是自己,负数补码=反码+1

而1的补码:正数补码是自己,负数的补码=各位取反(也就是反码)

IP/TCP首部校验规则:(摘自:http://www.cnblogs.com/fhefh/archive/2011/10/18/2216885.html,这篇讲解非常棒,有例子)

P/ICMP/IGMP/TCP/UDP等协议的校验和算法都是相同的,算法如下:

在发送数据时,为了计算数IP据报的校验和。应该按如下步骤:
(1)把IP数据报的首部都置为0,包括校验和字段。
(2)把首部看成以16位为单位的数字组成,依次进行二进制反码求和。
(3)把得到的结果存入校验和字段中。
在接收数据时,计算数据报的校验和相对简单,按如下步骤:
 
(1)当接收IP包时,需要对报头进行确认,检查IP头是否有误,算法同上2、3步,然后判断取反的结果是否为0,是则正确,否则有错。
 
1、发送方
  i)将校验和字段置为0,然后将IP包头按16比特分成多个单元,如包头长度不是16比特的倍数,则用0比特填充到16比特的倍数;
 
  ii)对各个单元采用反码加法运算(即高位溢出位会加到低位,通常的补码运算是直接丢掉溢出的高位),将得到的和的反码填入校验和字段;
 
  iii)发送数据包。
 
2、接收方
  i)将IP包头按16比特分成多个单元,如包头长度不是16比特的倍数,则用0比特填充到16比特的倍数;
 
  ii)对各个单元采用反码加法运算,检查得到的和是否符合是全1(有的实现可能对得到的和会取反码,然后判断最终值是不是全0);
 
iii)如果是全1则进行下步处理,否则意味着包已变化从而丢弃之。需要强调的是反码和是采用高位溢出加到低位的,如3比特的反码和运算:100b+101b=010b(因为100b+101b=1001b,高位溢出1,其应该加到低位,即001b+1b(高位溢出位)=010b)

程序:

 unsigned short checksum(unsigned short *buf, int nword)
{
// short是16位(俩字节),即把报表首部按16bit分开
// 先求和
unsigned long sum = ;
for(int i=; i<nword; i++)
{
sum += *buf++;
}
//高位溢出加到低位
sum = (sum >> ) + (sum & 0xffff);
//防止上次操作引起的新溢出
sum += (sum >> );
//long(32 bit) 截取低位部分转换为short(16位)
return (unsigned short)~sum;
}

IP首部之首部校验和的更多相关文章

  1. IP数据包的校验和算法

    1.算法思路: IP/ICMP/IGMP/TCP/UDP等协议的校验和算法都是相同的,算法如下: 在发送数据时,为了计算IP数据包的校验和.应该按如下步骤: (1)把IP数据包的校验和字段置为0: ( ...

  2. HTTP协议图--HTTP 报文首部之首部字段(重点分析)

    1.首部字段概述 先来回顾一下首部字段在报文的位置,HTTP 报文包含报文首部和报文主体,报文首部包含请求行(或状态行)和首部字段. 在报文众多的字段当中,HTTP 首部字段包含的信息最为丰富.首部字 ...

  3. [TCP/IP] 网络层-抓包分析IP数据包首部

    ip数据包的结构:首部+数据部分 1.版本(v4或者v6)+首部长度(固定的20字节,所以就没有)+区分服务优先级(我的例子是 assured forwarding 31 0x1a 26,保证转发) ...

  4. TCP/IP UDP 协议首部及数据进入协议栈封装的过程

    数据的封装 UDP 封装 TCP 封装 IP 封装 检验和算法 当应用程序用TCP传送数据时,数据被传送入协议栈中,然后逐一通过每一层直到被当作一串比特流送入网络 注: UDP数据TCP数据基本一致. ...

  5. WireShark开启IP, TCP,UDP校验和的办法

    首先点击编辑->首选项

  6. IP数据报首部校验和算法

    当用google搜索IP数据报首部校验和算法的时候,总是看到的是代码,没有看到其过程,于是就有了此文,如有错误请指正.文章省略一点,呵呵   IP/ICMP/IGMP/TCP/UDP等协议的校验和算法 ...

  7. IP 首部检验和算法

    原创博文,转载请注明出处. 在学习TCP/IP 详解的过程中遇到了不止一次的关于检验和的概念,在吸取了他人理解的前提下,我决定用Wireshark 进行抓包分析. 首先我们得知道IP数据包格式 首先把 ...

  8. 理解传输层中UDP协议首部校验和以及校验和计算方法的Java实现

    UDP,全称User Datagram Protocol,用户数据报协议,是TCP/IP四层参考模型中传输层的一种面向报文的.无连接的.不能保证可靠的.无拥塞控制的协议.UDP协议因为传输效率高,常用 ...

  9. TCP/IP协议栈--IP首部选项字段的分析

    IP输入函数(ipintr)将在验证分组格式(检验和,长度等)之后.确定分组是否到达目的地之前,对选项进行处理. 这表明分组所 遇到的每一个路由器以及终于的目的主机都对要分组的选项进行处理. IP分组 ...

随机推荐

  1. java十分钟速懂知识点——System类

    上次面试中遇到的一个问题,问到System.out.println()中的out是不是内部类,当时就给问蒙了,直观感觉out应该是System类的一个属性,跟内部类有什么关系?而且之前整理IO部分的时 ...

  2. vue/vux编译时出现 unexpected token <11:0-485>

    最近开发Vux项目,一直使用VS Code开发工具,可以格式化里面的<script>代码的: 但是今天突然无法格式化代码,而且编译报错.主要提示类似:unexpected token  & ...

  3. 33、secret

    CemFjee9rueuoeeQhgkxCee9kee7nO+8jOW6lOeUqO+8jOaVsOaNruW6k+acjeWKoeeahOWFs+mUruS/oeaBr++8iOWmgiDmnI3l ...

  4. IOS开发学习笔记033-UIScrollView

    1.滚动显示图片 如果图片过大,则需要滚动显示,这是需要用到类UIScrollView,可是实现控件的水平和垂直滚动. 可用三步实现:1 设置UIScrollView,2 设置UIImageView, ...

  5. 2018安恒杯11月月赛 MISC

    题目放评论了 Numeric password 这次隐写没有按照套路出牌,很强. 记录一下 看来自主学习的能力很有待提高. 打开Numeric password.txt 中华文化博大精深,近日在教小外 ...

  6. Spring boot 整合jsp、thymeleaf、freemarker

    1.创建spring boot 项目 2.pom文件配置如下: <dependencies> <dependency> <groupId>org.springfra ...

  7. Notadd 2.0 全新 Node.js 版本~ (开发中) [从 PHP 到 node 的踩坑记]

    对于 Notadd 我们本来期望它实现更多... 尽管我们也尝试做了很多努力,但是由于 PHP 本身的局限,以及考虑到开发环境配置的复杂程度,最终使用了折中方案.接下来,我们谈谈整个技术选型历程,也供 ...

  8. Python的网络编程socket模块

    (1)利用socket进行简单的链接 Python里面的socket支持UDP.TCP.以及进程间的通信,socket可以把我们想要发送的东西封装起来,发送过去,然后反解成原来的样子,事实上网路通信可 ...

  9. jsp运行机制

    一.JSP机制概述 可以把执行JSP页面的执行分成两个阶段,一个是转译阶段,一个是请求阶段. 转译阶段:JSP页面转换成Servlet类. 请求阶段:Servlet类执行,将响应结果发送至客户端. 1 ...

  10. [SDOI2009][bzoj1878] HH的项链 [莫队模板题]

    题面: 传送门 思路: 就是一道莫队的模板题目...... 开一个1000000的数组记录每个数出现的次数,然后每次从1到0或者从0到1更新答案 莫队讲解看这里:莫队 Code: #include&l ...