我们在对网络分层的了解上知道IP实际上是为路由找方向属于网络层协议,比如说唐僧去西天取经IP地址就是西天,MAC地址则是下一个目的地的地址,比如说唐僧到了女儿国,国王说你下一站应该去火焰山,女儿国国王为什么知道唐僧的下一站是火焰山,就是根据IP地址判断的。
IP提供了一种能力,可以将数据从A主机跨网络送到B主机,但是有能力一定会做到吗?
苗苗有能力考100分,那么她每次考试都是100分吗?
当然不是啦,但是即使苗苗考了98分,我们也不能说她没有能力考100分
可是如果非要让她考100分呢?
我们普通学生没有能力让她重新考试,但是学校的领导可以啊,学校的领导可以让考试反复进行,直到苗苗考100分
所以说,能力只是决定了将该事情办成的几率大,并不确定一定能完成。要想IP一定将数据从主机A跨网络传送到主机B,它的上层也就是TCP可以控制它,如果传送失败,反复传送 ,直到传送到为止。
假设你在北京有个朋友,想要来你的学校看你,问你怎么走?
你会告诉他直接坐飞机到你的学校吗…
除非你的学校有飞机场
你当然会告诉他,你先到哪个城市,然后转什么什么交通工具…
对应到网络中,要想将数据从主机A传送到主机B,就必须先到主机B所在的网络。唐僧想去西天取经,就必须先到西天,然后在西天找相应的地方,并不是佛祖就在西天的入口等他。
IP地址 = 网络号+主机号 路由器就是根据网络号找下一个地址的方向。
4位首部长度 和TCP报头中的4位首部长度一样,代表的是IP报头的长度是多少个4字节,4位比特位能够表示的最大数字是15,即IP头部的最大长度是15*4 = 60字节
16位总长度 指的是IP数据报整体占多少个字节
8位协议 表示上层的协议类型
数据链路层MAC针的最大传送单元MTU为1500字节,所以对于较大的IP数据包要进行分包。
就像是我们寄一个重20公斤的快递,但是顺丰快递的极限是五公斤,我们就必须分四次进行发送,所以IP有一个重要的功能分片,对方收到数据后,由于分片收到的数据是不完整的。所以IP还必须有一个组装功能
假设顺丰的丢包率是2%,我们分四次进行传送,对方收到完整包的概率就为:98%*98%*98%*98% 可见分片后丢包的几率就大了,我们还是尽量应该不分片的好。
数据链路层能接收的最大报文是1500字节
即证明IP报文+有效载荷的最大值是1500 IP报头是20字节,也就是IP的有效载荷为1480字节
IP的有效载荷即为TCP报头+TCP有效载荷,TCP报头也是20字节,所以TCP的有效载荷就为1460字节
即就是如果TCP传入的有效载荷不大于1460字节就不会被分片(MSL)
但如果超过1460字节就必须分片。
如何分片?
13位分片偏移量是分片相对于原始IP报文开始处的偏移量,即就是表示当前分片在原报文处的哪个位置 非0 ,即就表示该片是分片。但是问题来了,假设收到的报文是分片第一片,偏移量为0,怎么区分它是分片还是完整报文呢?3位标志位 第三个标志位为1代表有更多分片 ,为0代表无分片。
如何组装?
根据13位分片偏移量和3位标志位确定该报文不是完整的报文,需要组装 ,在分片时同一个报文的各个分片16位标识相同,IP协议根据16位标识和分片偏移量将报文组装起来,但是怎么确定,分片的结束呢,还是上面所说的3位标志位,第三个标志位为0标识后面再无其他分片了。
在组装时根据偏移量排序,偏移量+自己的长度 = 下一个报文的偏移量
,如果不是,接收方IP的16位校验和就会出错,将数据丢弃,则证明丢包了,启动重传机制,但是TCP都不知道IP分片了,也就更加没办法知道哪一片丢了,TCP就会整体重传。
(1500 - 20(IP首部)-8(UDP首部))
那么就会在网络层分成对个IP数据报IP地址分为两个部分:网络号和主机号
上文提到要想将数据从主机A传送到主机B,就必须先到主机B所在的网络。
我们举个例子吧,就说大学里的学号,根据学号我们可以精确的对应到一个人。
假设我们计算机学院有一个群,文理学院有一个群…各个学院都有自己对应的一个群,各个学院的群主之间又有一个校群。
某天我们捡到了一张一卡通,上面有对应的学号,我们怎么找到失主呢?
守株待兔吗? 路过一个人抓住问是不是你的一卡通?直到找到失主吗?
事实告诉我们并不需要这样,我们只需要拍张照片发到自己学院的群里@群主 告诉他你捡到了一卡通,学院的群主经常混迹于各个学院之间,认识这个一卡通属于的学院,去校群里@相应的学院负责人,这个相应的负责人就去自己的学院里找相应的人,这样很快的就可以将卡归还失主。
如果不划分网段,直接拿IP地址找主机,是不是就是像守株待兔一样,一个主机一个主机的遍历,但是有了网段划分,一次就可以排除多个网络
划分网段的主要目的就是为了提高效率。
过去曾经提出一种划分网络号和主机号的方案,把所有IP地址分为五类
A类: 0.0.0.0到127.255.255.255.255
B类:128.0.0.0到 191.255.255.255
C类:192.0.0.0到223.255.255.255
D类:224.0.0.0到239.255.255.255
E类:240.0.0.0 到 247.255.255.255
随着互联网的飞速发展,这种划分方案的局限性很快就显示出来,大多数组织都申请B类网络地址,导致B类地址很快就分配完了,而其他类却浪费了
针对这种情况提供了一个新的划分方案称为CIDR
IP地址和子网掩码还有一种更简洁的表示方式,例如140.252.20.68/24,表示IP地址为140.252.20.68,子网掩码的高24位时1也就是255.255.255.0
IPv4是一个4字节32位的正整数,那么一共只有2的32次方个IP地址,大概是43亿左右,而TCP/IP协议规定,每个主机都需要有一个IP地址,这意味着,一共只有43亿主机能接入网络吗? 实际上 ,由于一些特殊IP的存在,数量远不足43亿,另外IP地址并非是按照主机台数来配置的,而是每一个网卡都需要配置一个或多个IP地址
CIDR一定程度上缓解了IP地址不够用的问题(提高了利用率,减少了浪费,但是IP地址的上限没有变)仍然不是很够用,这时候又有了三种解决办法:
私有IP地址只在局域网出现,不同局域网内私有IP可以重复,但是公网IP不可以重复。
假设上图中,建立请求
源IP:192.168.1.200
目的IP:122.77.241.3
服务器收到后,响应请求
源IP:122.77.241.3
目的IP:192.168.1.200
但是192.168.1.200为 私有IP 仅在局域网内有效,在不同的局域网内有可能重复,所以在整个网络中有可能有成百上千个192.168.1.200,具体发给谁是不确定的,但是我们可以确定的是在建立连接时,源IP肯定不是我们所理解的192.168.1.200
那么究竟是怎么传输的呢?
子网内的主机需要和外网进行通信时,路由器将IP首部中的IP地址进行替换(替换成WAN口IP),这样逐级替换,最终数据包中的IP地址将变成为一个公网IP,这种技术成为NAT(网络地址转换)
建立请求
源IP:192.168.1.200
目的IP:122.77.241.3
到达家用路由器
源IP:192.168.1.1
目的IP: 122.77.241.3
到达运营商路由器
源IP:10.1.1.1
目的IP:122.77.241.3
服务器收到后,响应请求
源IP:122.77.241.3
目的IP:10.1.1.1
但是知道目的IP为10.1.1.1,怎么将响应送还到192.168.1.200呢?
在NAT路由器内部,有一张自动生成的,用于地址转换的表,当192.168.1.200第一次向122.77.241.3发送数据时就会产生映射关系
如果局域网内多个主机都访问同一个外网服务器,那么对于服务器返回的数据中,目的IP都是相同的,那么NAT路由器如何判定将这个数据包转发给哪个局域网的主机?
这时候NAPT使用IP+port
来建立这个关联关系
路由器起着路由的作用,可是路由器怎么知道,你的数据下一次去的是A站而不是B站呢?
某年,我们考上大学,做火车来到火车站,不幸的是,手机钱包都丢了,我们怎么去学校呢?
刚好在火车站看见了一位扫垃圾的大爷
我们兴致勃勃的跑过去问路
大爷啊,我想去****大学,怎么走啊?
假设即使大爷不知道路,也会竭尽全力帮助别人
情景一:
大爷说:我也是刚来不久,你去问那个大妈,她家住这里,方圆几公里,她都认识路
情景二:
大爷说:沿着这条路直走,右拐两次,在问别人
此时我的长途跋涉开始了,不断的问路,前进,直到有人说:你想找到的地方就是这儿。
那么问题来了,在问路的过程中,别人怎么知道你应该朝哪里走呢?想想我们在问路的时候,是不是首先要告诉别人想要去哪里,别人才会做出想应的回应。
对应到网络中:IP数据包的传输过程也和路由一样
假设某主机上的网络连接配置和路由表如下:
Destination | GateWay | Genmask | Flags | Metric | Ref | Use | Iface |
---|---|---|---|---|---|---|---|
192.168.10.0 | * | 255.255.255.0 | U | 0 | 0 | 0 | eth0 |
192.168.56.0 | * | 255.255.255.0 | U | 0 | 0 | 0 | eth1 |
127.0.0.0 | * | 255.0.0.0 | U | 0 | 0 | 0 | l0 |
default | 192.168.10.1 | 0.0.0.0 | UG | 0 | 0 | 0 | eth0 |
这台主机上右两个网络接口,一个网络接口连到192.168.10.0/24,另一个网络接口连到192.168.56.0/24网络
转发过程中,如果要发送的数据包的地址是192.168.56.3
转发过程中,如果要发送的数据包的地址是202.10.1.2