话说校验和(checksum)

2023-12-18 04:32
文章标签 校验 checksum

本文主要是介绍话说校验和(checksum),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载自:https://blog.51cto.com/fengyun/472114

话说校验和(checksum)

推荐 原创

拿贝马凡2011-01-05 10:51:16©著作权

文章标签 职场 tcp/ip 休闲 文章分类 tcp/ip协议 阅读数 40512

  好久没有写博文了,貌似不是没有时间,而是我比较懒,懒得打字,懒得动手。

这几天正在学习tcp/ip,一心血来潮,来看看校验和吧,检验和在链路层有,网络层有,传输层也有(udp与tcp都有,只不过tcp的是必须的,udp是可选的字段)。

注:ipv4版本有ip header 的checksum,而ipv6取消ip header的checksum,所以他的上层传输层就必须要有checksum(ipv4中的上层udp的checksum是可选字段)

先来看看链路层的frame format吧:标准的ethernet II的frame,rfc894定义的:

destination mac addresssource mac addresstype        data          fcs         

source 与destination mac address各占6个字节,type占2个字节,fcs就是frame checksum seq占4个字节

在这里说下:最小的data部分为46个字节

The minimum length of the data field of a packet sent over an
Ethernet is 46 octets.

不管是router还是各个操作系统,如果data不足会不让你发送的,router我记得是36个字节,不足的他添加垫片

。抓个包看看吧:

 
  1. C:\>ping -l 1 192.168.1.1 
  2. Pinging 192.168.1.1 with 1 bytes of data: 
  3. Reply from 192.168.1.1: bytes=1 time<1ms TTL=255 
  4. Reply from 192.168.1.1: bytes=1 time=12ms TTL=255 
  5. Reply from 192.168.1.1: bytes=1 time=10ms TTL=255 
  6. Reply from 192.168.1.1: bytes=1 time=10ms TTL=255 

看到了吧,这么算下,一个packet最少为64个字节,减去frame header 14个字节(source与destination各6个字节,type字段2个字节)与fcs 4个字节,为64-18=46个字节。

上图中增加17个字节的垫片,加上ip header length为20个字节,icmp为8个字节,1个字节的数据部分

20+8+1+17=46个字节。(插一句话:一个switch的检测收到的frame一般就是检测前64个字节后转发)

另外链路层如何知道一个frame是ip,arp,rarp是根据type字段来的。然后在做相应的处理,比如说type为0806.就知道这个是个arp frame,交给arp好了,如果是这个0800,往上层网络层交就可以了。至于他怎么处理,那就不管我的事情,你网络层去解决吧。

看完链路层,在看看网络层把,网络层的协议太多了,ip,ipx,appletalk做为运载工具,为什么ip能做为tcp/ip协议栈的核心,所有的tcp,udp,icmp,igmp数据都由ip数据包格式来传输。

看看ip数据包格式吧

Version

Header length

Tos

Total length

标识符

df

Mf

偏移位

Time to live

Protocol

Checksum

Source address

Destination address

Option

 ip 数据报的字段为:

4个bit的version

4个bit的header length(ipv6中没有这个字段,因为ipv6固定为40个字节)因为有ipv4 数据报头部固定为20个字节,但是有option这个选项。所以用于标识ip header length)

8个bit的tos,前3位用于优先级(现在用的很少,主要用于qos)---这个字节我也不是很清楚。有那位精通,欢迎指教。

16个bit的报文总长度。

16个bit的标识符与16个bit偏移位(加有3个bit标志),主要用于报文分片。

8个bit的ttl值,本来是指经过一台设备所需要的时间,用1s就减去1s,现在是指跳数,经过一台router就减去1.

8个bit的protocol号,这个是标识协议的,是指为谁的数据进行传输,协议号6标识是tcp,17是udp,这时ip包就将数据向传输层交了,由上层的tcp与udp来处理了,如果是1,就交由icmp来处理。跟链路层的type意义差不多。

16个bit的校验和,---今天的重点。

32个bit的source ip address

32个bit的destination ip address

最大40个字节的option选项

里面记录经过的路由(只能记录9个ip 爱到底,因为最大只有40个字节,一个ip地址占4个字节,还有3个字节的指针),指针等等,抓个包看看

 
  1. C:\>ping -r 9  220.181.111.85 
  2. Pinging 220.181.111.85 with 32 bytes of data: 
  3. Reply from 220.181.111.85: bytes=32 time=46ms TTL=53 
  4.     Route:          
  5.            61.190.244.97 -> 
  6.            118.84.1.1 -> 
  7.            202.97.66.69 -> 
  8.            220.181.16.13 -> 
  9.            10.65.190.164 -> 
  10.            10.65.190.21 -> 
  11.            220.181.111.85 

看到没有最大的ip header length为60个字节。

来说校验和,校验和应该叫16进制反码求和,就是将所有的字节加起来,再由ffff来减得到的值。

我这来计算ip header 的checksum,其他的校验和计算方式一样的

看header checksum为0X495c

整个ip header去除49 5c,为45 00+00 1d+6d 5e+80 01+c0 a8+01 d4+c0 a8+01 01=2B6A1(至于为什么00 00不加不解释)

2B6A1=B6A1+2=b6a3

ffff-b6a3=495c

看结果出来了吧,校验和是个很粗糙的计算方式(与md5相比),如果你source 与destination调换一下,结果相同,在链路层计算正确后到达网络层,经过ip头部校验可能还会出错,到达tcp或者udp也还可能出错,只是方便了网络设备的计算。当然你从source发往destination与destination发往source校验和肯定不会相同,应该里面的ttl与标识符会有差别。

在说下分片

分片的大小看接口的mtu值,而ethernet II的frame格式,data部分为1500个字节(这个data字段包括高层的信息与data)

咱来ping个大点的数据报,看操作系统是怎么处理的,ip header那些字段会有变动

 
  1. C:\>ping -l 6000 192.168.1.1 
  2. Pinging 192.168.1.1 with 6000 bytes of data: 
  3. Reply from 192.168.1.1: bytes=6000 time=3ms TTL=64 
  4. Reply from 192.168.1.1: bytes=6000 time=3ms TTL=64 
  5. Reply from 192.168.1.1: bytes=6000 time=2ms TTL=64 
  6. Reply from 192.168.1.1: bytes=6000 time=2ms TTL=64 
  7. Ping statistics for 192.168.1.1: 
  8.     Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), 
  9. Approximate round trip times in milli-seconds: 
  10.     Minimum = 2ms, Maximum = 3ms, Average = 2ms 

 分片的目的是数据包太大,超过了接口的mtu值,所以必须将传输的数据包分成小于接口mtu值的大小传输。

destination设备为什么知道他分片,怎么将那几个片组合成一个数据包,靠的就是ip 头部中的标识符,标志与偏移位。(这里为什么ip数据报为6008,而不是我指定的6000字节,因为增加了8个icmp的头部)

一个完整的数据报别分片,但是每片的标识位都是一样的,这样目的设备知道了这时同一个数据报的分片。

 虽然抓的这个是最后一个分片,但是前面每个分片的这个字段都是一致的

另外看标志(flags)

第3个比特没有啥用途,或者是我不知道

第2个比特是标识是否分片。如果是1就是不分片,0为分片

第3个比特是标识是否有下一个分片。只有最后一个分片这位为0,其他的都为1.

这个是不允许分片的结果

 
  1. C:\>ping -f -l 1600 192.168.1.1 
  2. Pinging 192.168.1.1 with 1600 bytes of data: 
  3. Packet needs to be fragmented but DF set. 
  4. Packet needs to be fragmented but DF set. 
  5. Packet needs to be fragmented but DF set. 
  6. Packet needs to be fragmented but DF set. 
  7. Ping statistics for 192.168.1.1: 
  8.     Packets: Sent = 4, Received = 0, Lost = 4 (100% loss), 

 偏移位(Fragment offse)标识(前面)发送了多少个字节的数据,这里是5920,即前面已经发送5920个字节,这里是最后一个分片,5920+88=6008.

如果分片会有那些字段改变呢,

看上面ip header的图

第一片

ip headeroptionprotocols上层portdata

其他片

ip headerdata

首先,version是不会改变,不会从v4版本变成v6版本的

           header length肯定会发生变化,比较你增加了option,header length会增加,而在分片时第一片会携带这个,但是后面的每片都不携带这个选项。

tos不会发生变化

total length会发生变化,最后一个分片除非正好与其他片的一样大(这样的比较巧合)

标识符(Identification)不会发生变化,只有下一个数据报才会发生变化,一变化就不是同一数据包的了

标识(flags)会发生变化,主要是mf,让目的知道最后一片

偏移位(Fragment offse)会发生变化,知道传了多少个字节了

生存时间(time-to-live)不会发生变化,你每个片除非经过不同的路径

协议号(protocol)不会发生变化,变化就乱了,我ip为谁传输来着

校验和(checksum)会发生变化,option选项都不加了,肯定有

source ip address:不会发生变化,参考协议字段

destination·ip address:不会发生变化,参考协议字段

 在看看udp的格式

Source port

Destination port

Length

checksum

2个字节的source port

2个字节的destination port

2个字节的长度,这里包括了整个udp头部与数据部分

2个字节的checksum(可选字段)

所以说udp的最小为8个字节

这篇关于话说校验和(checksum)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/507052

相关文章

校验码:奇偶校验,CRC循环冗余校验,海明校验码

文章目录 奇偶校验码CRC循环冗余校验码海明校验码 奇偶校验码 码距:任何一种编码都由许多码字构成,任意两个码字之间最少变化的二进制位数就称为数据检验码的码距。 奇偶校验码的编码方法是:由若干位有效信息(如一个字节),再加上一个二进制位(校验位)组成校验码。 奇校验:整个校验码中1的个数为奇数 偶校验:整个校验码中1的个数为偶数 奇偶校验,可检测1位(奇数位)的错误,不可纠错。

web登录校验

基础登录功能 LoginController @PostMapping("/login")Result login(@RequestBody Emp emp) {log.info("前端,发送了一个登录请求");Emp e = empService.login(emp);return e!=null?Result.success():Result.error("用户" +"名或密码错误");

checksum 与 CRC的不同之处

实际应用: CRC:在外发电压时,在报文的最后两个字节做了CRC计算。 checksum : 在按键状态外发,在报文的最后一个字节做了checksum计算。 它们的共同之处:目的都是为了数据的错误检测功能。 只是在算法的复杂度上有较大的区别: 总的来说,CRC算法更复杂,可检测的错误也比较丰富。 CRC与checksum的计算方式都是固定的吗? 在实际应用中,并没有通知对方,所用

spring数据校验Validation

文章目录 需要的依赖创建校验对象Validator 需要的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency> 创建校验对象Validator 测试的实体类 //创建实体

spring项目使用邮箱验证码校验

本项目采用免费QQ邮箱验证码方式进行登录安全的校验。 前期工作 申请邮箱安全授权码 打开QQ邮箱官网点击设置 进入设置页面后点击账户按钮  进入账户后一直往下拉页面找到POP3服务栏,然后点击管理服务(如果没有开启服务需要先开启服务,按照邮箱提示操作即可) 进入管理服务页面后如果没有授权码,点击生成授权码,如果有即可进入授权码管理页面查看。 授权码过一段时间会自动过期,需要重

zdppy+vue3+onlyoffice文档管理系统实战 20240906 上课笔记 整合权限校验中间件

基于角色方法的中间件基本用法 import zdppy_api as apiimport zdppy_apimidauthasync def index(request):return api.resp.success()async def login(request):token = zdppy_apimidauth.get_role_token(role="admin")return ap

Spring源码学习--使用XML Schema文档对XML实例文档校验

文章摘要 在实际开发中读取xml文档的时候,一般都需要先校验,如果使用Sun的XML相关软件包会令你云里雾里。W3C这块的XML相关的规范相当的多,这也是导致XML处理器起来费劲的主要原因。如果xml对应的xsd文档已经定义好,则可以之间复用下面代码对xml文档格式和内容是否合法进行验证。 一、xsd校验xml工具类 import javax.xml.parsers.SA

struts2 xml validator 校验

分类: 【字段校验】  ---- field-validator   ---- 字段优先,我去校验谁(字段),我用谁(校验器)来校验 【非字段校验】  ---- validator  ---- 校验器优先,我用谁(校验器)来校验,我去校验谁(字段) ****** 这两种只是  表现形式  不同,底层是相同的,都是把错误信息放到fielder

【LoRa】打开硬件CRC校验功能,但没有起作用?

目录 1 前言2 解析3 结论 1 前言 在使用LoRa模式(非FSK)时,可能遇到明明RX端已经打开CRC校验了,为什么payload错误了,没有报CRC error中断?本章就这个问题展开讲讲,如何正确使用芯片的硬件CRC校验,并延申到CR和payload length的使用。 2 解析 确实存在前言中的现象,前提是使用的explicit header模式,即有heade