最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

网络层-IP协议

运维笔记admin26浏览0评论

一 网络层的意义

    ip地址是子网划分的结果,网络层要做的就是根据目的ip地址路由选择去下一个路由器,下个路由器继续路由,最终送到目的主机,这中间两个主机间如何通信是由数据链路层决定的,路由器可以看成特殊的主机。

注意:tcp发送报文一般也只是把报文给下一层,一般情况下,中间设备识别报文最多到ip层,不关心tcp报文,是的,因为知道目的ip就知道往哪里发送了,没必要解析tcp报文。显然ip报文有效载荷就是tcp报文。tcp是保证可靠性,ip是帮助报文抵达到对端,tcp不是能保证可靠性吗,为什么还要ip层。

        ip层作用:帮助数据从A主机到B主机,不过只是较大概率发送到目标主机,但不一定能保证百分百送到,因为中途可能有些设备损坏,导致报文无法抵达,(这里只是说ip帮助发送,不是直接负责发送,整个发送动作还需要数据链路层来配合)我们需要tcp协议的可靠性策略来保证重传。

二 ip报文的认识

        去广州的时候,我们一般是先到广东省,再去广州,而对应到32位ip地址,则是一个网络号+这个网络内的某个主机号,显然主机是被划分在一个个网络中,后面再来了解网络划分以及为什么要网络划分。

        路由器和主机的区别,主机也转发报文,路由器也转发报文,但是路由器要选择路径(路由)转发,还要对收到报文做处理的,将报文的私有ip地址进行切换,怎么处理后面要结合nat理解。

        ip协议报头,也是固定的二十字节,也有选项,4位首部长度记录报头总长度。

        8位协议是表明传输层报文用得是哪个协议,表明tcp就会调用tcp协议的处理函数解析ip的有效载荷,解析完后将载荷放到传输层缓冲区,所有客户端报文都在一个缓冲区吗,我们之前创建套接字,我们知道这个是文件描述符,再细说其实这个文件描述符对应的文件缓冲区就是传输层缓冲区,每次创建套接字,就会在底层创建接收和发送缓冲区,tcp报文里面有端口号,底层绝对维护了传输层缓冲区和目标端口号的对应关系,不然仅凭端口号找到进程,然后找到文件符表是无法确定哪个文件描述符是网络文件。

        4位版本表明ip版本,一般是ipv4,并不兼容ipv6。可是ip协议层是os中的,虽然更换一层协议,对其它层协议无影响,但是我们要更新成ipv6就要改os,而且是全部的os都要改,这很麻烦,必须要大部分国家都同意才能推ipv6,所以我们国家ipv6一般是在内网中推行,也就是本国通信用ipv6,公网通信一般还是ipv4,那什么是公网,国际间网络通信就是公网,那我们怎么和外国通信,可以由路由器做适配,也就是路由器对转发报文的报头做更换。(这就是主机和路由器的不同之处)

        ip层实际上是给tcp层提供服务将报文传送到对端的服务的,那ip层就像是快递员,有多种服务供我们选择,例如最高可靠性,就是让ip报文在传输时选择可靠的路径,还有最小延时就是要找最快路径,所以就有了8位服务类型来提醒中途的网络设备提供什么类型的服务。

其中3位是优先字段(已经弃用),4位TOS字段,分别标志最小成本,最高可靠,最小延时等服务,1位保留字段。

16位总长度,注意:先前tcp报文是不记录自己的大小的。因为tcp报文是面向字节流的,直接将滑动窗口中的数据往下发,而ip是面向数据报的,必须保证能切割出一个ip报文,所以需要制定报文大小。

        为什么tcp是面向字节流,下层又是面向数据报,什么时候面向字节流,什么时候又面向数据报呢? tcp要管理很多报文,面向字节流实际上是为了提高缓冲区管理数据效率,而ip层报文不需要管理旧的报文,也就不用面向字节流。

生存时间TTL

        数据本质是光电信号,这些信号会衰减,而中间节点为保证这个信号能到下个节点,会对报文信号做放大。如果报文一直不消失,就会一直在节点环回发送,一直占用网络资源,更到不了对端,我们很难保证路由器不会环回发送,所以给报文带上最大转发次数,免得一直被转发。

      为什么报文要有目的ip和目的端口,简单理解就是中间路由器转发时需要读取目的ip地址来路由转发。此时我们的报文字段大致解释的差不多了,还有的字段后面再提。

三 网络划分

 1 为什么要网络划分

        我们先前说了32位的ip中,有一部分比特位表示网络号,另一部分表示主机号。为什么要分这两部分其实就是问为什么要将网络划分成一个个子网,我们下面提及。

        我们是如何根据ip地址找到主机的呢,难道是遍历全网主机吗? 那找到都得猴年马月了,如果我们拿到了一个学生的学生卡,我们要把卡给他,我们可以根据学号判断这个是不是我们学院的,因为我们也有学号,也知道学号有几个数字是表示学院,所以一对比就知道是不是自己学院的了,不是我们就转发给辅导员,因为他认识其它学院的辅导员就能把卡给到失主所在学院。

        主机就和学生一样是会被划分到不同区域,每个区域是一个子网,子网标识符叫网络号,所以我们查找主机也可以分区域排查。实际上排查过程就是路由,路由器链接了多个子网,发送报文时也能分清楚这个报文的目的ip地址是不是自己链接的子网。如果报文不是发给自己链接的子网,会采取默认转发,具体细节在路由的时候再说。

        ip地址的构成是子网划分的结果,为什么要子网划分? 显然是为了提高路由查找效率。

2 子网划分介绍

        那什么是子网划分?  如何理解子网划分和查找过程。子网中的设备为什么可以直接通信? 慢慢来说,首先国内的网络一定是由运营商设计管理的,运营商为了提高路由查找效率,对整个国家进行了网段划分,国际上则是国家之间商量着来。

         我们先按照国家划分网络,例如下面三个国家主机的ip地址前面的网络号是不同的。

        此时在中国境内的主机ip地址就必须都是128开头,因为这是规定,所有人必须遵守,你不遵守到时候路由器就会把你的报文转发错误,路由器厂商一定会遵守,因为这种划分方式对他来说只有好处,没有坏处,因为对于路由器来说今后只要遇到128开头的ip地址报文,它立刻就知道是中国的,应该转发给中国的路由器,瞬间就排除了美国和俄罗斯,这种排查方式是很高效的。

        随后我可以继续对中国境内做子网划分,

        由此我们可以发现网络号越来越长,主机号越来越短,直到最后定位到一台主机。

        例如上面这个的网络号是192.168.128,下面是192.168.144,显然是两个不同的子网,网络划分后这两个子网间如何通信呢? 由路由器集连,首先我们先认为路由器可以给一个子网内的主机发消息(再次强调,如何发是数据链路层解决的),简单理解就是两个子网内的主机和路由器是通过无线或者有线方式连接的,两个子网内的主机要通信,就可以将消息给路由器,由路由器去转发。

        路由器横跨多个子网,作为子网和子网之间的链接,那路由器就必须有两个ip地址,这样才属于某个子网。集连多个子网也就表示路由器身处两个子网,也就和多个子网的主机相连接,既能给上面的子网发,也能给下面的子网发。所以只要下面这个子网内的主机把报文转给路由器,路由器就可以转发到另一个子网了。

        有时候可能不是一个路由器就能够转发成功了,例如广东省下某个子网要和广西省下某个子网通信,路由器会不断将数据默认转发给上一级(此时路由器也是连接多个子网,一个是源主机,另一个是和上级路由器),各级路由器都发现不是自己链接的子网,最后给了省级路由器,省级路由器之间是一个子网,就直接转给了广西省的根路由器,这个过程就像是在找最近的公共祖先一样。

3 ip分类

        ip地址的32位哪些位是网络号,哪些是主机号呢,这个都由划分方案来规定,之前的划分方案是五类划分。为什么要有五类划分,不同国家网民数量不同,主机数量不同,就划分了不同的ip地址给不同的国家。如下图,A类ip网络号占位少,适合给大国家。

第一个比特位为1表示不是A类,第二个表示不是B类。不同类的ip地址网络号和主机号占用不同的比特位,所以要有比特位区分不同类别的ip地址。

局限,ip地址本来都不够资源了,你现在还要拿几个比特位去标识不同的网络。

新方法,我们引入一个子网掩码子网掩码是左边全是1,右边全为0的数字,每个子网络都有个子网掩码,只要将ip地址和子网掩码按位与,就能得出ip地址的网络号,剩下的就是主机号,所以只要和每个子网网络号一对比就知道是不是属于这个子网内的了。

        例如,有个ip地址是128.2.1.1到了下面中国这个入口路由器,中国路由器和一个个省级子网的入口路由器都在一个子网内,由于各个省份内的主机各自形成一个子网,所以我们可以说,中国路由器也就链接了一个个省级子网,同时中国路由器保存了各个子网的网络号,将报文ip地址和子网掩码一按位与,一对比就发现是广西的报文,就转发给广西的入口路由器了。

4 再谈划分

        上面的ip地址划分,我们会发现,我们不能一直按地区划分下去? 不然ip地址不够,你想想32个比特位,只能标识四十亿台主机,你想想中国大部分基本都有台手机,电脑,这些都要接入互联网,ip早就没了。

        这里其实有个非常重要的概念,公有ip和私有ip,我们前面都是拿公有ip在划分。现实生活中不是每台主机都接公网(将公网ip分给主机),而是划分到某个阶段,就开始给主机分配私有ip,这就是nat技术,大大减少了公有ip的短缺,事实上也的确如此,公网ip可以在国际上标识唯一一台主机,可以用来国际间通信,我们很多人就不需要公网ip,有几个人需要和外国主机通信的。所以我们可以在国内一些子网通信用私网ip就可以是全零到全1了?也不是,讲私有ip会提及。

四 路由查找

1 路由

         前面提及了很多前置知识,现在要再提路由,路由器集联多个子网,会保存子网的网络号和子网掩码,这个数据并不多,只要用每个子网的子网掩码和报文ip地址按位与,再和子网网络号比对,如果属于这个子网,我们可以直接转发给管理这个子网的路由器,由这个路由器给主机。这两个路由器之间的通信就是子网内通信,会有数据链路层解决,路由就是要找到下一个主机的mac地址,方便子网内通信。

        所以下面这个子网地址是从8C FC 14 40开始,能改变的只是最后一个16进制位,这个部分才是主机号,所以最大为8C FC 14 4F。对应140.252.20.79。

    

2 私有ip

        一般私有ip只用于内网通信,是不会用于公网的,按理说我们是可以让私有ip从全零到全1的,但是官方规定了私有ip的构成。如下。

        这使得公有ip又少了一点,当然也就少几百万,这显然是对一个子网用私有ip能链接的主机做了限制。在一个子网内全用私有ip,私有ip可以重复,因为两个拿着重复私有ip的主机不在一个子网内,这样对于一个一个城市内的主机就可以用私有ip,甚至一个城市太大,还可以对城市再划分子网。

先抛出一些问题,私网ip可以重复,遗留1 那它们通过会重复的私有ip是如何通信的如何定位到一台主机呢,那是报文中的是什么ip。这个和nat技术相关,还是要在数据链路层提及,下面先浅浅了解一下。

3 浅谈nat技术

        两个主机都拿的是私有ip,如何通信? 这个时候就又要引入新概念了。lan口ip和wan口ip。lan口ip一开始是主机的ip, wan口ip是国内公网分配给路由器的ip,也有可能是某个子网的私有ip。

私有ip不能出现公网,因为私网ip会重复。所以在将报文给路由器,我们要逐步将报文中的lan口ip换成路由器的ip,这就是在不断地替换报文源ip,最终替换成公网路由器ip。这样在返回的时候才能在公网环境找到能转发回给我们的公网路由器。但是这个公网路由器如何转回给我们的主机,这得后面提及。简单的说就是路途中的每个路由器肯定都记录先前的源ip,这样才能替换回去,定位到原来的主机。

        这种ip不断被替换的技术就叫nat技术,我们发现a往b发消息时,会将自己的私有ip逐渐换成公有ip,最后主机b是和这个公网ip对应的路由器在通信,同理我们主机a也不是和主机b通信,而是和某个公有ip的路由器在通信。

五 分片和组装

首先为什么tcp为什么不是将滑动窗口内的所有数据一次性发送,而是要分段发送? 难道下层对大小有限制?是的。

    1 ip分片介绍

ip报文还剩下下面的16位标识,还有3位标志和13位片偏移,我们后面要一一介绍,先介绍分片。

       遗留问题2,3 1为什么要分片,因为数据链路层规定发送单元大小不能超过MTU,从而推出tcp报文载荷上限为mss。问题2 为什么这么规定呢? 这个问题留到数据链路层解释,原理非常容易理解。问题3 什么是分片,分片的好处的答案同样在数据链路层,所以若是tcp报文太大了,就需要ip层进行分片,拆分成一个个小报文给数据链路层发送。

        问题4 为什么是ip进行分片呢? 应用层,传输层,数据链路层不行吗如果传输层实现了分片,网络层也要实现,不然怎么管理传输层给你的分片,这就冗余了,那数据链路层呢,数据链路层是驱动底层网线硬件干活的,所以如果硬件不同,驱动程序也不一样,也就是说不同的主机的数据链路层是可能不同的,如果要在这层实现分片,那就要在各种类型的数据链路层中实现分片。

        问5 tcp报文大小没超过mss,为什么中途还会分片,因为我们主机一般mtu设为1500,但是中间的路由器不一定设为1500,可能更小,所以我们的报文在到该路由器的时候会被分片传输。调小的意义:可以减少分包,站在路由器角度,它要往一些子网络中发报文,这些子网的mtu是未知的,因为不同地区的无线和有线通信设施数量不同,导致mtu的选择不同(无线mtu貌似会偏小,有线会偏大),若是网络mtu小于路由器的mtu,会导致路由器发出的报文大多要分片,为了减少这个分片,我们将路由器的mtu调小了。

2 遗留字段解释

        3位标志:第一个比特位保留,第二个比特位标识是否禁止分片,可是如果报文长度大于mtu,此时报文会被丢弃,不会再进行分片,第三个比特位表示分片结束符,0表示当前ip报文是最后一个分片,说明后面没有分片了,也可以说明不分片。

        13位片偏移表示当前片在原始报文的起始偏移量,以字节数为偏移量。如下,一个4500字节的报文就被分成了三个部分,这三个部分大家的16位标识都是一样的,假设为1234,

        第二行的0,1表示当前分片是否为结束分片,第三行为偏移量,分别是0,1500,3000。16位标识(1234)是标识同一个tcp报文的一部分,到时候按照偏移量组装到一起。

         我在搜的资料发现,有不少说ip层没有接受和发送缓冲区,但是ip层会收到很多上层交付的tcp报文,他们可能都是不同进程发的,肯定是要有发送缓冲区各自分开保存的,然后就根据大小判断要不要分片,不要就直接转交给数据链路层的发送缓冲区,同时ip层也会收到不同主机发的ip报文,肯定也要根据ip报文中的源ip来分别创建一个缓冲区,在缓冲区中对一定时间内收到的分片进行排列,齐了就向上交付,不齐就丢弃,对端超时重传。

        16位标识的作用: 标识是同一tcp的分片,那标识会重复吗。首先服务端会收到各个客户端的报文,十六位标识是会重复的,但是我们可以先根据源ip做区分,再根据标识区分。

3 分片和组装

1 如何区分分片? 靠ip报文中的源ip和16位标识字段,就能区分出分片是否是同属于一个tcp报文的。

2 如何知道报文分片了

        知道是否分片了,意义是什么? 可以对报文采取不同的措施,不分片那就不用等待一段时间去收集其它分片,分片了就要考虑是否收集全的问题。

        禁止分片标识符能表示无分片,因为只有报文超过一定大小才会分片,如果禁止分片,然后报文又比较大,此时就直接丢弃了,所以只要收到禁止分片的报文一定是无分片的。当更多分片和片偏移全为0时表示独立报文,全不为0,表示分片了,而且当前报文是中间报文,1,0表示是起始报文,0,1(1表示某个不为零的数字)标识终点报文。

3 如何组装,如何保证收全了

        为了收集一个tcp完整报文。就要先找到开头,中间,结尾报文,所以我们只要识别出这三种报文就好了。前面已经知道了如何区分这三种报文,所以我们只要把收到的报文按照偏移量大小组放在缓冲区,然后线性遍历缓冲区,我们就知道报文是否完整了。

5 如何知道组装的分片是对的

        就是用下面的校验和,这个校验和是校验ip报头,每个ip报文通过校验和说明报头(片偏移,3位标志等字段)没问题,那组装就不容易出问题。

        而tcp报文校验码恰好可以用来校验ip层的组装结果,因为ip最后是要组装成tcp报文的,这样就ip和tcp就打起了配合。

最后一个问题,如果某个分片丢失,ip会直接丢弃,对端会重发整个报文,不是某个分片,如果真是针对某个分片重发,那tcp首先肯定要知道你这报文分了哪几片,然后哪片丢了,可是分片是在ip层,难道还要将分片结果往上层报吗,耦合度太高。

4 分片的缺点

        分片容易导致丢包,一个报文在网络丢失假设是万分之一,你现在分成五个报文去发送,此时丢包率就增加为万分之五,如何减少分片只能让tcp少传点数据,就是让tcp的滑动窗口内的数据分多次发,这实际上也体现了tcp的可靠性和效率,减少丢包率,减少重传次数。

        tcp一次最多从滑动窗口拿多少数据去发呢,就是一个MSS,最大段尺寸。而MTU则是数据链路层一次性发送的最大报文,我们知道这个报文里面包含着ip报文,ip报文里包含着tcp报文,所以MSS是根据主机的MTU推导出来的。

发布评论

评论列表(0)

  1. 暂无评论