三十天学不会TCP,UDP/IP网络编程-IP头格式祥述
我又来了,这篇文章还是来做(da)推(guang)介(gao)我自己的!俗话说事不过三,我觉得我下次得换个说法了,不然估计要被厌恶了,但是我是好心呐,一定要相信我纯洁的眼神。由于这两年接触到了比较多的这方面的知识,不想忘了,我决定把他们记录下来,所以决定在GitBook用半年时间上面写下来,这是目前写的一节,后面会在gitbook上不断更新,欢迎大家star,主要是在写完之前欢迎各位给出指正的意见。最最重要的,地址在这里:https://www.gitbook.com/book/rogerzhu/-tcp-udp-ip/,或者在gitbook上搜索“三十天学不会TCP,UDP/IP编程”。
这是第一次在这一系列文章里面详细介绍一个数据包格式,在计算机网络编程上面,数据包格式可能是接触的最多的一个概念了。如果你要实现一个什么协议,第一件事应该就是搞清楚数据格式,我的做法一般都是先看一遍数据包的文档,在纸上画一遍数据包,然后再打开wireshark,对着抓到的包多鼓捣几遍一般就差不多能掌握了。
IPv4头数据包
一个IPv4数据包格式如下所示(倾情献上我的手绘版):
除去最后的data部分就是一个IP头数据包了,那么就从最低位开始一一开始详细介绍,下面的单位都是位,不是字节:
基本信息
0-3: 版本,标识了IP头的版本,IPv4里面自然这个值是4(0100)。
4-7: IP头的长度,以32bit word为单位,一共四位,所以最大长度是15*32bit,也就是60个字节,注意这是头的长度,而不是IP数据包最大的长度。按照图中的格式,去掉Data和If any的option部分,可以一共数出来是5行,也就是5个32bit长度,那么可以得出IP头最少也要20个字节,所以这个字段最小值是5,小于这个值都是不合法的。
8-15: TOS,全称Type of service, 这个字段是根据有些特殊的网络状况的不同来定义想IP层提供怎样的服务的。比如在有的网络上希望有的数据包可以优先得到传输,因为他们可能含有相对于其他数据包来说,比较重要的信息。这三个字段来完成这一服务的本质就是在三个方面提供一个平衡,这三个方面就是,低延迟,高可靠性和高吞吐量。具体来说可以将这个8位分为5个部分:
- 8-10: 优先级
- 11: 1代表开启低延迟模式,0代表关闭
- 12: 1代表开启高吞吐量模式,0代表关闭
- 13: 1代表开启高可靠性模式,0代表关闭
- 14-15: 保留位
优先级的仍然可以展开成为8个不同的级别,不过一般这种单纯罗列的东西超过三层就基本上会产生发散注意力的尿性,所以就不展开了,只要能记住这个3位用来表示数据包的不同的重要性或优先级就行了。后面三位就是从三个不同的角度来促使某个数据包能够因为其重要性最先被处理。但是在大多数网络中,真的要同设置了三位,那么反而会导致更差的后果。因为在很多情况下,这三个本身就是鱼和熊掌不可兼得的,所以一般只需要选择一个就好,很少的情况下需要打开两个。
16-31: 总长度字段,总长度是以字节(8 bit)为单位的,包括头部长度,所以说一个IP数据包最长是65,535个字节。不过一般这么长的数据包一般都是不切合实际,所以说在最初的标准里推荐的是不超过576个字节,包括头部的长度。
标识与分片
32-47:标识符,用来标识和归组数据包,为什么要归组呢?因为如果一个数据包比较大,往往就需要分片,分片简单的说就是把一个大的IP数据包分成好几包小的,为了标哪些是哪一个大包的组成部分,就需要一个标识符来组织他们,这样对端才能把分开的数据包重新组合成为一个整的数据包。但是可以看到,这个字段只有16个bits的长度,所以标识最多只可能有65536个不同的数,在现在一个数据包可能以十万百万计的网络通信上,就会出现一个问题,标识符在循环了一圈之后又要出现重复的数啦。这个问题咋办呢?答案是简单的丢弃数据包并且发送标识错误的信息给发送端。
48-50:分片标识,上面说了如果一个IP数据包过大,就需要分片,那么这个3个bit就用来表示该数据包的分片情况。其中
- 48: 保留位,必须为0
- 49: 0表示是分片的数据包,1表示不是分片的数据包
- 50: 0表示是一组分片数据包的最后一片,1表示后面还有分片的数据包
总结一下,其实就是这三位如果是000,就是表示这只是一组分片数据包中间的一片,如果是001就表示这是最后一片了,IP层可以根据需要组装数据包交给上一层,只要是01,后面以为就可以忽略了,因为这是一片完整的数据包。
51-63:偏移量,这个是配合标识符字段使用的,标识出改数据包在整个分片数据包的位置,这样才能让IP层按照正确的顺序拼凑出数据包。
生存和上层信息
64-71: TTL,数据包还剩的生存时间,这样翻译感觉有点挫,一般这个名词都不会被翻译,直接用英文的原文Time to live。这个值最初被设计出来的时候是以秒作为单位的,也就是该数据包还能存活多少秒,如果这个字段的值到0了,那么这个数据包就得消失了并且向发送端发送能标识错误的消息。但是由于现在路由器的处理时间和发送时间都远远小于1秒,所以这个慢慢的就被用作标识还能经过多少个路由器转发,俗称跳数,现在一般都标为128。但是在一些特殊的测试目的的场景下,我们就可以利用这个字段来测试出发送主机和目的主机之间的路径信息。
72-79:协议,就是标识这个IP数据包的data是啥协议,常见的比如TCP,UDP。
80-95:头部效验和,这是使用CRC算法来检测头部,注意,仅仅时检测头部信息有没有错,如果有错那么该数据包将不得通过。
地址信息
96-127: 发送端IP地址,32位。
128-159:接收端IP地址,32位。
选项(如果有)
这个选项字段是IP层数据包为了配合一些其他协议的发送或者应答而应运而生的,如果只是单纯的列出有哪些选项保证就会被滚轮滚过去,而且大部分是根本不会遇到的,所以我决定再介绍ICMP的时候再介绍我能接触到的。
如何记忆数据包格式
我觉得这是如果涉及网络编程的一个难题,因为有太多协议了,不可能把所有数据包的格式都记住,但是这也不代表啥数据包格式都记不住。在我看来,最基础的比如IPv4的头数据包格式,TCP的格式,UDP的格式,ICMP,ARP大概的样式都应该记住,虽然说这些玩意儿一百度就能百度出来,但是我觉得在面试时这些都是能反应你熟练程度的一个参考吧。
经过我的几次探索,我觉得我找到了一条适合我的方法,就是用笔画一画。我觉得计算机一个最大的弊端就是让人们忘了笔和纸的作用,很多时候动动手真的能加深大脑的记忆,虽然我也不知为什么。第二个就是分类,比如这个IP头吧,我会把他主要分为上面黑体字的那几类,结合着几类,其实再加一些简单的逻辑推理就不难记住这些。比如基本信息,基本信息嘛,总要有长度,版本号嘛,再对照书一看,真有,但是少了一个TOS,没关系,这是特殊的功能,不在人脑一般认知的基本信息之内,这一次的miss hit就可以让你记住有一个TOS,强化了记忆。
抓个活物来看看
在对这个包头格式有一定了解的基础上就可以找一个真实的IP数据包看看,一是加深印象,二是看看随着年代的发展,标准里会不会有坑。我还是用哪个SMB数据包来观察一下:
展开IP这一层的信息,wireshark已经把一串二进制翻译成了人眼可见的信息,当然,你要是有兴趣也可以在二进制信息里自己寻找和发掘。我感觉这东西和考古差不多,在一堆一眼看上去差不多的东西里面发现自己需要的,偶尔弄弄还是很有成就感的,搞多了伤眼睛。
对比第一个部分介绍的,可以看到这个IP头是20个字节,也就最小长度,没有选项。有一个天蓝色的字段上面貌似没有找到,但其实这就是TOS字段,有兴趣可以搜一下这个名词,还是很复杂的。不过因为是0,就认为啥也没有发生就行。还可以看到标识符,这个数据包并不分片,是一个整体。还有就是这个IP数据包里所蕴含的是一个TCP的数据,也可以看到两个IP地址。
所以说,至少在相信wireshark的情况下,标准并没有坑我,或者说SMB发送的IP包是符合标准的额,我们可元气满满的额进入下一个话题了。
三十天学不会TCP,UDP/IP网络编程-IP头格式祥述的更多相关文章
- 三十天学不会TCP,UDP/IP网络编程-ARP -- 连接MAC和IP
继续来做(da)推(guang)介(gao)我自己的!由于这两年接触到了比较多的这方面的知识,不想忘了,我决定把他们记录下来,所以决定在GitBook用半年时间上面写下来,这是目前写的一节,目前已完成 ...
- 三十天学不会TCP,UDP/IP编程--MAC地址和数据链路层
这篇文章主要是来做(da)推(guang)介(gao)的!由于这两年接触到了比较多的这方面的知识,不想忘了,我决定把他们记录下来,所以决定在GitBook用半年时间上面写下来,这是目前写的一节,后面会 ...
- 三十天学不会TCP,UDP/IP网络编程-TraceRoute的哲学
新年快乐,继续来部分粘贴复制我的这一系列文章啦,如果对和程序员有关的计算机网络知识,和对计算机网络方面的编程有兴趣,欢迎去gitbook(https://www.gitbook.com/@rogerz ...
- 三十天学不会TCP,UDP/IP网络编程-UDP,从简单的开始
如果对和程序员有关的计算机网络知识,和对计算机网络方面的编程有兴趣,欢迎去gitbook(https://www.gitbook.com/@rogerzhu/)star我的这一系列文章,虽然说现在这种 ...
- 三十天学不会TCP,UDP/IP网络编程 - 绅士的开始
经过了过年的忙碌和年初的懈怠一切的日子,我又开始重新更新了~这是最新的一篇~完整版可以去gitbook(https://www.gitbook.com/@rogerzhu/)看到. 如果对和程序员有关 ...
- 三十天学不会TCP,UDP/IP网络编程 - RST的用法
不知不觉也写了这么多了,继续我的自己的推广大业~完整版可以去gitbook(https://www.gitbook.com/@rogerzhu/)看到. 如果对和程序员有关的计算机网络知识,和对计算机 ...
- 三十天学不会TCP,UDP/IP网络编程 - UDP的实践--DHCP
在经历了一顿忙碌加出去玩了玩之后,我又开始重新更新了~这是最新的一篇~完整版可以去gitbook(https://www.gitbook.com/@rogerzhu/)看到,在gitbook的后台流量 ...
- 三十天学不会TCP,UDP/IP网络编程 -- TCP中的智慧之连续ARQ
突然发现上一篇文章贴图有问题,关键我怎么调也调不好,为了表达歉意,我再贴一篇gitbook上的吧,虽然违背了我自己的隔一篇在这里发一次的潜规则~其余完整版可以去gitbook(https://www. ...
- 三十天学不会TCP,UDP/IP网络编程 -- RTT的计算
欢迎去gitbook(https://www.gitbook.com/@rogerzhu/)看到完整版. 如果对和程序员有关的计算机网络知识,和对计算机网络方面的编程有兴趣,虽然说现在这种“看不见”的 ...
随机推荐
- Problem V
Problem Description The aspiring Roy the Robber has seen a lot of American movies, and knows that th ...
- Tickets
Tickets Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Stat ...
- 分析Array.apply(null, { length: 5 })
Array.apply(null, { length: 5 }) 和 Array(5)有什么不同 注意:ES5,apply函数的第二个参数除了可以是数组外,还可以是类数组对象 // 类转成真正的数组 ...
- JAVA 通过 Socket 实现 TCP 编程
简介 TCP简介 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的计算机 ...
- 使用Node.js+Socket.IO搭建WebSocket实时应用【转载】
原文:http://www.jianshu.com/p/d9b1273a93fd Web领域的实时推送技术,也被称作Realtime技术.这种技术要达到的目的是让用户不需要刷新浏览器就可以获得实时更新 ...
- Photoshop 学习中
快捷键: f8打开信息调板,注意虽然数字最高是255,但0也是数值之一,因此共256级. f7开启图层调板 f6调出调色板,按D还原为默认颜色 ctrl + 放大,ctrl - 缩小 f 可以切换显示 ...
- 分享如何将git项目导入GitHub(附创建分支)
前言:我们应该很多都会有自己的私有项目,大多情况都是存放在自己的硬盘中,今天我分享一下怎么讲自己的私有项目更新到GitHub上,这样再也不用担心项目丢失了. 一:下载git 下载链接git链接,根据自 ...
- python迭代器以及itertools模块
迭代器 在python中,迭代器协议就是实现对象的__iter()方法和next()方法,其中前者返回对象本身,后者返回容器的下一个元素.实现了这两个方法的对象就是可迭代对象.迭代器是有惰性的,只有在 ...
- Filezilla账号密码都正确,但是连不上
显示的错误信息是:服务器发回了不可路由的地址.使用服务器地址代替. 之前一直用CuteFTP把ssm项目发送给客户服务器,最近学习大数据用Filezilla连通虚拟机,感觉Filezilla很直观.就 ...
- 你是如何自学 Python 的?
作为一名Python爱好者,我也想跟大家分享分享我自学Python的一些小经验.搬来你的小板凳,听听看吧.也许,你会很有收获,也许你也走上了自学Python的不归路.开讲啦~ 首先,你要有自信心,要明 ...