首先介绍一下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. time模块和datetime模块详解

    一.time模块 time模块中时间表现的格式主要有三种: a.timestamp时间戳,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量 b.struct_time时间元组,共 ...

  2. 设计模式之第3章-模板方法模式(Java实现)

    设计模式之第3章-模板方法模式(Java实现) "那个,上次由于我老婆要给我做饭,所以就没有说完就走掉了...这个那个".这次和以前一样,先来开场福利(工厂方法模式已被作者踹下场) ...

  3. linux环境搭建系列之tomcat安装步骤

    前提: Linux centOS 64位 JDK 1.7 安装包从官网上下载 安装Tomcat之前要先安装JDK. 我的JDK是1.7版本的,所以Tomcat版本也选了7的 1.新建目录tomcat ...

  4. Mac OS使用brew安装memcached

    1.查看安装信息 brew info memcached 显示如下: memcached: stable 1.5.9 (bottled) High performance, distributed m ...

  5. centos php环境搭建

    CentOS 6.5系统安装配置LAMP(Apache+PHP5+MySQL)服务器环境 准备篇: 1.配置防火墙,开启80端口.3306端口vi /etc/sysconfig/iptables-A ...

  6. Leetcode 600.不包含连续1的非负整数

    不包含连续1的非负整数 给定一个正整数 n,找出小于或等于 n 的非负整数中,其二进制表示不包含 连续的1 的个数. 示例 1: 输入: 5 输出: 5 解释: 下面是带有相应二进制表示的非负整数&l ...

  7. Unity3D - 设计模式 - 工厂模式

    工厂模式:以食物生产为例 1. 一个生产食物的工厂(此项 需要建立两个类:食物基类<Food>,工厂类<Factory>) 2. 可以生产不同的食物(此项 建立食物的具体子类, ...

  8. Linux内存使用消耗高

    Linux系统下如果内存占用很高又找不到是被什么程序占用的,需要考虑下是否是SLAB的问题.SLAB是Linux操作系统的一种内存分配机制,可以使用下面命令来查看.例如: cat /proc/memi ...

  9. Python之面向对象:封装

    1.封装的概念 将对象的数据与操作数据的方法相结合,通过方法将对象的数据与实现细节保护起来,就称为封装.外界只能通过对象的方法访问对象,因此封装同时也实现了对象的数据隐藏. 在使用面向对象的封装特性时 ...

  10. python(4)-- 日期 & 时间

    1. Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间. 2. 时间间隔是以秒为单位的浮点小数. 3. 每个时间戳都以自从1970年1月1日午夜(历元)经过了多长 ...