目录
📕引言
🌴IP协议的概念
🌳IP数据报
🚩IPv4协议头格式
🚩IPv6的诞生
🏀拓展
🎄IP地址
🚩IP地址的格式:
🚩IP地址的分类
🏀网段划分
🏀网络号与主机号的划分
🚩特殊的IP地址
🚩子网掩码
🏀计算方式
📕引言
IP协议是网络层重点协议,其重要作用是:在复杂的网络环境中确定一个合适的路径。
下面只对该协议简单介绍
🌴IP协议的概念
IP指网际互连协议,Internet Protocol的缩写,是TCP/IP体系中的网络层协议。设计IP的目的是提高网络的可扩展性:一是解决互联网问题,实现大规模、异构网络的互联互通;二是分割顶层网络应用和底层网络技术之间的耦合关系,以利于两者的独立发展。根据端到端的设计原则,IP只为主机提供一种无连接、不可靠的、尽力而为的数据包传输服务。
🌳IP数据报
🚩IPv4协议头格式
- 4位版本号(version)
指定IP协议的版本,对于IPv4来说,就是4。如果是6,就是IPv6(上述是IPv4的报头结构)
- 4位头部长度(header length)
IP头部的长度是多少个32bit,也就是 length * 4 的字节数。4bit表示最大的数字是15,因此IP头部最大长度是60字节,最短20个字节(选项)。
- 8位服务类型(Type Of Service)
3位优先权字段(已经弃用),4位TOS字段,和1位保留 字段(必须置为0)
4位TOS分别表示:最小延时(传输过程中消耗时间最短),最大吞吐量(单位时间内传输的数据尽可能多),最高可靠性(降低丢包的概率),最小成本(比较节省系统开销)。
这四者相互冲突,只能选择一个。对于ssh/telnet这样的应用程序,最小延时比较重要;对 于ftp这样的程序,最大吞吐量比较重要
- 16位总长度(total length)
IP数据报整体占多少个字节(报头+载荷)
TCP中没有记录自身长度,可以通过IP的总长度,去掉IP首部长度,剩下的载荷就是TCP的总长度,去掉TCP的报头,剩下就是TCP载荷的长度
16位总长度是字节数,也就是前面说的UDP数据报最大64kb,那么这里也是IP数据包也不能超过64kb?
IP自身实现了拆包组包这样的功能,如果携带的载荷,超出长度上线,IP就会自动拆分成多个数据包,每个数据包携带一部分,发送到对方之后,在拼接好。
具体流程:
当前A给B传输一个数据,当前有一个TCP数据包,假设这个数据很长,超过了64kb
A这边再封装成IP数据包的时候,就会把TCP数据包拆成多分(假设3份),使用多个IP数据包进行发送
对于IP数据包来说,他并不关心所要传输的数据里面到底是什么样的,直接简单粗暴的把这个数据分成几份,每一份都装到IP的载荷里面,然后统一发送给B。
那么B是如何知道,收到的IP数据包如何合并?
IP报头中的16位标识,3位标志位,13位片偏移这三个属性就是用来实现IP的拆包组包的
- 16位标识(id):
唯一的标识主机发送的报文。如果IP报文在数据链路层被分片了,那么每一个片里面的这个id都是相同的。就是用来区分哪些数据包要合并
- 3位标志字段:
第一位保留(保留的意思是现在不用,但是还没想好说不定以后要用到)。第二位用来表示,该数据包是否触发了拆包的效果(是否需要组包)。第三位是结束标记位,当前包就是最后一个需要组包的部分。
- 13位分片偏移(framegament offset)
就是若干要拼接的数据包的先后顺序,根据片偏移来区分出谁在前,谁在后。
说到这里,就会有一个问题,TCP超过64kb了,IP就会进行拆包组包,那UDP超过64kb了,IP不能进行拆包组包吗?
假设有一个很长的UDP数据包:
直观上看起来,把上述数据拆分成多个IP数据包发送,好像也是ok的。我们拆分之后,传输过去上述数据也能还原成原始的模样。
但是呢,我们知道,在A和B进行通信的时候,这个中间要进行封装分用,当我们把数据进行组包完成之后,要交给传输层,也就是UDP进一步的进行使用,在UDP这一层,要对上述数据进行解析。也就是取出8个字节,作为报头,剩余部分作为载荷,剩下的载荷到底多长?就会尝试从报头中的报文长度字段来读取,读出来的数字最多还是64kb。
- 8位生存时间(Time To Live,TTL)
一个IP数据包,在网络上有一个转发的过程,转发的数据是根据你设定好的目的IP来进行转发,但是给定目的IP有问题,用于到不了,所以这里的TTL就是限制一个数据包在网络上转发的最大次数。每经过一个路由器,次数就会消耗掉一次。次数是32/64,一般是64(通常情况下64就够用了,背后有一个理论"六度空间",比如我想认识美国的川普,大概率经过6层朋友的转发,就能够练联系到世界上任何一个人)。一旦达到0,这个数据包就会被丢弃掉。
当前此台电脑连的路由器,TTL为64就说明中间没有经常其他设备转发。
如果去ping一个比较远的服务器,TTL为53,就说明此台电脑到搜狗的服务器,这中间经过多次的路由器转发。
- 8位协议:
描述了 载荷部分是哪种协议的数据包,也就是交给UDP还是TCP,表示上层协议的类型。一个数据包在分用的时候,要交给上层哪个协议,都是有明确声明的。
传输层=>应用层:通过端口号来区分
网络层=>传输层:报头中有这个8位协议字段
数据链路层=>网络层:报头中也有一个字段来区分是交给IP协议,还是其他协议
- 16位头部校验和
使用CRC进行校验,只是针对IP首部进行校验,载荷部分不关系
- 32位源地址和32位目标地址
表示发送端和接收端
讲述过,为了让人更方便的观察,把32位的整数通常用点分十进制方式来表达。那么32位也表示42亿9000万,原则上来说,不同设备,IP地址应该是唯一的,不重复,上述这个数字,在今天来说,显然是不够用的!!!当今社会,移动互联网的发展,一个人就可能两个手机。
IP地址不够用,还怎么办,共有三个方案。
方案一:动态分配IP地址(DHCP)
某个设备,上网路由器就分配,不上网就不分配(这样的机制只能缓解,不能从根本上解决)。
方案二:NAT机制网络地址转换(网络地址映射)
首先把IP地址分为两个大类
此时约定,公网IP唯一,私网IP允许在不同局域网中重复,虽然能上网的设备很多,绝大部分IP都在局域网内,也就是局域网1中的设备IP和局域网2中的设备IP可以重复。NAT机制也没有增加IP地址,但是极大的提高了IP地址的复用情况,使用一个公网IP,代表一组设备。
NAT机制下的几种情况:
简化:
发送给服务器:
服务器返回响应:
注意:我们的私网IP并不是运营商路由器提供的,上述只是简图,在这中间我的电脑是连的家里的路由器,即我的私网IP是有家里的路由器分配的。
问题
上述一个局域网下只是一台电脑访问,那如果同一局域网下是又有一台电脑访问cctalk服务器呢?
发送数据:
返回响应:
那么还有问题
那如果这两台主机的端口号碰巧是一样的(端口号碰巧一样,是小概率事件),现在我们这个数据,经过运营商路由器进行NAT的替换,注意,此时的映射表,旧端口的两台主机仍然是1234,但是第二台主机的新端口还是让他为5678。新端口和旧端口不一定要必须一样,是可以变化的,新端口都是由路由器自己分配的,他是可以很轻松的知道是不是已经重复了,只要分配出一个唯一的端口号出来即可。后序的转发过程和上述仍然一样。
问题
不同局域网的内网ip可以重复,那么同一个运营商路由器的不同局域网,运营商返回请求的时候是怎么分辨出是哪个局域网中的内网ip?
当前的网络世界,就是通过动态分配 + NAT机制解决IP不够用的问题的~~
NAT机制确实能解决,但是这样的方案又给网络的复杂程度增加了不少,而且也没有重根本上的解决,如果随着设备进一步的增多,一个外网NAT设备上面最最多只能有6w多个表项,NAT也可能不够用了。
🚩IPv6的诞生
自从1970年代IPv4问世以来,数据通信技术日新月异有了很大发展。虽然IPv4设计得很好,但其缺点也逐渐显露出来:
- 虽说借助子网化、无类寻址和NAT技术可以提高IP地址使用效率,因特网中IP地址的耗尽仍然是一个没有彻底解决的问题;
- IPv4没有提供对实时音频和视频传输这种要求传输最小时延的策略和预留资源支持;
- IPv4不能对某些有数据加密和鉴别要求的应用提供支持。
为了克服这些缺点,IPv6(Internet working Protocol version6)被提了出来。
IPv6拿16个字节表示IP地址,有128,这就是一个天文数字了,足以给地球上的每一粒沙子分配一个唯一的IP地址。
- 在IPv6中,IP地址格式和分组长度以及分组的格式都改变了。IPv6每个分组由必须的基本头部和其后的有效载荷组成。
- 有效载荷由可选的扩展头部和来自上层的数据组成。
- 基本头部占用40字节,有效载荷可以包含65535字节数据
那为啥世界上还以IPv4为主呢?
🏀拓展
🎄IP地址
IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异
🚩IP地址的格式:
IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节),如:01100100.00000100.00000101.00000110。
通常用“点分十进制”的方式来表示,即 a.b.c.d 的形式(a,b,c,d都是0~255之间的十进制整数)。如:100.4.5.6
🚩IP地址的分类
🏀网段划分
IP地址是用来识别网络上的设备,因此,IP地址是由网络地址与主机地址两部分所组成。
- 网络地址
网络地址可用来识别设备所在的网络,网络地址位于IP地址的前段。当组织或企业申请IP地址时,所获得的并非IP地址,而是取得一个唯一的、能够识别的网络地址。同一网络上的所有设备,都有相同的网络地址。IP路由的功能是根据IP地址中的网络地址,决定要将IP信息包送至所指明的那个网络。
- 主机地址
主机地址位于IP地址的后段,可用来识别网络上设备。同一网络上的设备都会有相同的网络地址,而各设备之间则是以主机地址来区别。同一个局域网内,网络号相同,主机号不同。
搭配子网掩码的网段划分是现在的方法,下面按照ABCDE类来划分仅存于教科书上。
🏀网络号与主机号的划分
过去曾经提出一种划分网络号和主机号的方案,把所有IP 地址分为五类,这个体系下没有子网掩码什么事,如下图所示
- A类0.0.0.0到127.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
🚩特殊的IP地址
- 将IP地址中的主机地址全部设为0,就成为了网络号,不应该分配给具体主机,即使分配了也上不了网(192.168.1.0);
- 将IP地址中的主机地址全部设为1,就成为了广播地址(192.168.100.255 / 24),用于给同一个链路中相互连接的所有主机发送数据包;TCP不支持广播,UDP才支持
- 127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1 本机环回主要用于本机到本机的网络通信(系统内部为了性能,不会走网络的方式传输),对于开发网络通信的程序(即网络编程)而言,常见的开发方式都是本机到本机的网络通信。 例如之前写的TCP服务器/UDP服务器,客户端和服务器在同一个主机上,此时就可以是有环回ip来进行发送与接收。可以不用进行连网。
🚩子网掩码
在上述的分类中,存在IP地址浪费的问题:
(1)单位一般会申请B类网络(C类连接主机数量有限),但实际网络架设时,连接的主机数量又常远小于65534(B类连接主机数),造成IP地址浪费;同理,A类网络的IP地址也会造成大量的浪费。
(2)当一个单位申请了一个网络号。他想将该网络能表示的IP地址再分给它下属的几个小单位时,如果在申请新的网络就会造成浪费。
为了解决以上问题,引入子网掩码来进行子网划分:
- 子网掩码的格式:
子网掩码格式和IP地址一样,也是一个32位的二进制数。其中左边是网络位,用二进制数字“1”表示,1的数目等于网络位的长度;右边是主机位,用二进制数字“0”表示,0的数目等于主机位的长度。子网掩码也可以使用二进制所有高位1相加的数值来表示,如以上子网掩码也可以表示为24。
- 子网掩码的作用
(1)划分A,B,C三类 IP 地址子网:如一个B类IP地址:191.100.0.0,按A ~ E类分类来说,网络号二进制数为16位网络号+16位主机号。假设使用子网掩码 255.255.128.0(即17) 来划分子网,意味着划分子网后,高17位都是网络位/网络号,也就是将原来16位主机号,划分为1位子网号+15位主机号
此时,IP地址组成为:网络号+子网号+主机号,网络号和子网号统一为网络标识(划分子网后的网络号/网段)
(2)网络通信时,子网掩码结合IP地址,可以计算获得网络号(划分子网后的网络号)及主机号(划分子网后的主机号)。一般用于判断目的IP与本IP是否为同一个网段
🏀计算方式
将 IP 地址和子网掩码进行“按位与”操作(二进制相同位,与操作,两个都是1结果为1,否则为0),得到的结果就是网络号。
将子网掩码二进制按位取反,再与 IP 地址位与计算,得到的就是主机号。