目录
基本概念
IP报头
IP报文分片
为什么要分片?
如何分片?
分片的报文如何组装?
分片策略如何?
网段划分
IP地址被分成了五类IP:
CIDR
特殊的IP地址:
私有IP和公网IP
路由
如何转发数据包?
基本概念
主机:配有IP,不进行路由控制的设备
路由器:配有IP并进行路由控制的设备
节点:主机和路由器统称节点
前面提到传输层主要解决的是数据可靠传输的问题,而网络层主要解决的是让数据能在主机之间传输的能力:
IP协议:网际互连协议(Internet Protocol),是网络层重要的协议。
IP报头
字段含义:
4位版本:表示是IPv4还是IPv6协议。
4位首部长度(*4字节):表示报文首部长度,单位是4字节,因为IP报文的基本长度为20字节(不带选项时),所以至少是5。
8位服务类型:3位优先权字段(已经弃用), 4位TOS字段, 和1位保留字段(必须置为0),4位TOS分别表示:最小延时,最大吞吐量,最高可靠性, 最小成本。这四者相互冲突,只能选择一个,对于ssh/telnet这样的应用程序,最小延时比较重要;对于ftp这样的程序,最大吞吐量比较重要。
16位总长度:IP数据报整体字节数,包括报头和有效载荷
16位标识+3位标志+13位片偏移:用于IP报文分片的字段
8位生存时间(Time To Live, TTL):数据报到达目的地的最大报文跳数(hop),一般是64. 每次经过一个路由,TTL -= 1,一直减到0还没到达,那么就丢弃了。这个字段主要是用来防止出现路由循环。
8位协议:表示数据包要交付上层协议的类型
6位头部校验和:使用CRC进行校验,来鉴别报文头部是否损坏
32位源地址和32位目标地址:表示发送端的IP地址和接收端的IP地址
IP报文分片
为什么要分片?
链路层有发送单个数据帧的最大值的约束,所以不能发太大IP报文,这个约束就是MTU(最大传输单元),MTU一般是1500字节,可以通过命令ifconfig查看:
如何分片?
发送方的网络层分片,接收方的网络层组装,倘若丢了一片分片就相当于传输层整体丢包,所以分片会导致丢包概率会增加,尽量不分片。
当报文分片时是如何识别报文分片了?
三位标志中第一位保留,第二标记位表示禁止分片,如果标记为1,这时候如果报文长度超过MTU, IP模块就会丢弃报文,第三位标记位表示更多分片,如果分片了更多分片标记位就置1,最后一个分片更多分片标记位就置0,表示分片结束。
16位标识(id): 唯一的标识主机发送的报文。如果IP报文在数据链路层被分片了,那么每一个片里面的这个id都是相同的。
13位分片偏移(framegament offffset): 是分片相对于原始IP报文开始处的偏移. 其实就是在表示当前分片在原报文中处在哪个位置,实际偏移的字节数是这个值 * 8 得到的,所以在填入该值时就是报文实际相对报文起始的偏移/8,因此,除了最后一个报文之外,其他报文的长度必须是8的整数倍(否则报文就不连续了),所以就算先收到最后一个分片,虽然更多分片标记位为0,但因为其片偏移不为0,所以可以识别是分了片的报文。
分片的报文如何组装?
1.将相同序号的报文收集(16位标识相同的)
2.正确组装:根据13位片偏移排序,第一个报文的片偏移为0
怎么保证收完和收全报文?第一个片偏移为0,后面的报文的片偏移按报文长度累加,最后一个报文的第三位更多分片标记位为0。
分片策略如何?
应该尽量减少分片:分片会导致报文丢失概率增加,因为任意一个分片丢失,对于上层而言就是整个报文的丢失。对于TCP,在三次握手的时候就会协商单次传输数据都报文大小MSS=MTU-IP报文头部-TCP报文头部,可以保证不发生分片,但对于不可靠的UDP而言,分片会直接影响UDP报文数据丢失。但是分片方案值得学习和借鉴,特别是分片和组装只用了三个字段就完成了。
网段划分
IP地址被分为两部分:
网络号:标识不同网段的主机
主机号:同一网段的主机之间具有相同的网络号,但是主机号必须不同,而不同网段主机号可以不同
通过设置网络号和主机号就可以保证互相连接的网络中,每台网络的主机的IP地址都不相同,每个子网的网络号都相同,而主机之间的主机号不同,当子网中新增一台主机的时候就需要分配新的IP地址,这个分配任务是DHCP自动给主机分配IP,避免了手动分配IP地址的不方便,一般路由器带有DHCP功能,路由器可以看做一个DHCP服务器。
注:DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是基于UDP的应用层协议。
因为IP地址=目的网络+目的主机 ,所以数据在路由的时候可以根据不同的网络号先找到进行不同的网段然后在网段下在查找相应的主机,这样就可以提高效率。
IP地址被分成了五类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早已不足,而且存在问题,比如B类地址的主机号有16位,也即至多能运行6万多太主机在一个子网中,但是实际的网络架设中没有这么多主机,这样就会浪费IP地址,为了解决这个问题引入了CIDR(Classless Interdomain Routing),称为无类别域间路由:
CIDR
1.引入子网掩码来区分网络号和主机号
2.32位正整数,通常后面一串0来表示,子网掩码与IP地址按位与得到网络号
3.网络号和主机号的划分与这个IP地址是A类、B类还是C类无关
特殊的IP地址:
子网划分:便于查找目标主机
主机地址全0:网络号,代表这个局域网
主机地址全1:广播地址,用于给同一个链路中相连的所有主机发送数据包
127.*的IP地址用于本地环回,如127.0.0.1,发给本地的报文不必传递到IP下层:
1.动态分配IP地址:只给接入网络的设备分配IP地址。因此同一个MAC地址的设备,每次接入互联网中,得到的IP地址不一定是相同的2.NAT技术:通过路由器在数据通信的时候将私网IP转化为公网IP,从而使不同私网能有相同的私网IP,从而解决IP地址不足的问题3.IPv6: IPv6并不是IPv4的简单升级版。这是互不相干的两个协议,彼此并不兼容;IPv6用16字节128位来表示一个IP地址,理论上完全足够了,但是目前IPv6还没有普及
私有IP和公网IP
如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到Internet上,理论上 使用任意的IP地址都可以,但是RFC 1918规定了用于组建局域网的私有IP地址:
10.*,前8位是网络号,共16,777,216个地址
172.16.到172.31.,前12位是网络号,共1,048,576个地址
192.168.*,前16位是网络号,共65,536个地址
一个路由器可以配置两个IP地址,一个是WAN口IP,一个是LAN口IP(子网IP)。路由器LAN口连接的主机,都从属于当前这个路由器的子网中。不同的路由器,子网IP其实都是一样的(通常都是192.168.1.1)。子网内的主机IP地址不能重复,但是子网之间的IP地址就可以重复了。每一个家用路由器, 其实又作为运营商路由器的子网中的一个节点,这样的运营商路由器可能会有很多级,最外层的运营商路由器,WAN口IP就是一个公网IP了。子网内的主机需要和外网进行通信时,路由器将IP首部中的IP地址进行替换(替换成WAN口IP),这样逐级替换,最终数据包中的IP地址成为一个公网IP,这种技术称为NAT(Network Address Translation,网络地址转换),当数据从服务器返回时,目的IP都是相同的,这时用NAPT技术,使用IP+PORT来建立这个关联关系。如果希望我们自己实现的服务器程序,能够在公网上被访问到,就需要把程序部署在一台具有外网IP的服务器上。
路由
路由就是在复杂的网络结构中找出通往目的的线路。
对于每个节点而言,每个节点内部维护一个路由表,在Linux中使用route命令查看路由表:
如何转发数据包?
Destination:目的网络地址Genmask:子网掩码Gateway:下一跳地址Iface:发送接口Flags:U标志表示此条目有效(可以禁用某些条目),G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发
转发过程例1: 如果要发送的数据包的目的地址是192.168.56.3
跟第一行的子网掩码做与运算得到192.168.56.0,与第一行的目的网络地址不符
再跟第二行的子网掩码做与运算得到192.168.56.0,正是第二行的目的网络地址,因此从eth1接口发送出去;由于192.168.56.0/24正是与eth1接口直接相连的网络,因此可以直接发到目的主机,不需要经路由器转发;
转发过程例2: 如果要发送的数据包的目的地址是202.10.1.2依次和路由表前几项进行对比, 发现都不匹配;按缺省路由条目, 从eth0接口发出去, 发往192.168.10.1路由器;由192.168.10.1路由器根据它的路由表决定下一跳地址