Linux网络编程_01_网络基础
Linux网络编程_02_socket套接字
Linux网络编程_03_应用层HTTP协议
Linux网络编程_04_传输层UDP和TCP协议
Linux网络编程_05_网络层IP协议
Linux网络编程_06_数据链路层MAC帧协议
Linux网络编程_07_多路转接
4位版本号: 指定IP协议的版本,对于IPv4来说,就是4
4位头部长度: IP头部的长度是多少个32bit,也就是 长度 * 4 的字节数。4位最大的数字是15,因此IP头部最大长度是60字节。
8位服务类型: 3位优先权字段(已经弃用),4位TOS字段,和1位保留字段(必须置为0)。TOS分别表示: 最小延时(1000)、最大吞吐量(0100)、 最高可靠性(0010)、 最小成本(0001),一般服务(0000),只能选一个。
16位总长度: IP数据报整体占多少个字节
16位标识: 唯一的标识主机发送的报文. 如果IP报文在交付给数据链路层被分片了, 那么每一个片的标识都是相同的
3位标志字段: 第一位保留,第二位置为1表示禁止分片,这时候如果报文长度超过MTU(Maximum Transmission Unit最大传输单元),IP模块就会丢弃报文,第三位置为1表示后面还有分片
13位分片偏移: 表示当前分片数据开始位置在原报文中处在哪个位置。实际偏移的字节数是这个值 * 8 得到的,除了最后一个报文之外,其他报文的长度必须是8的整数倍,否则报文就不连续了
8位生存时间: 数据报到达目的地的最大报文跳数, 一般是64。每次经过一个路由, TTL -= 1, 一直减到0还没到达, 那么就丢弃了. 这个字段主要是用来防止出现路由循环
8位协议: 表示上层协议的类型
16位头部校验和: 使用CRC进行校验,来鉴别头部是否损坏
32位源地址和32位目标地址: 表示发送端和接收端.
选项: 不定长,最多40字节
数据链路层往网络里发送数据是有大小限制的,也就是不能超过MTU,CentOS7默认的MTU为1500,网络层的IP协议将数据报交付给数据链路层时整个报文最大只能是1500字节。如果我们传输层一个数据段过大那么就需要拆分发送,也就是进行分片,到了接收端再进行组合。
如图所示,如果一个数据包过大时,就会被分成很多部分发送,假设我们报头为20字节时,每个数据报的数据最多是1480字节。发送端将数据报分片,那接收端就需要组合起来。为了使组合时数据的有序性和完整性,需要用到IP数据报报头的16位标识,3位标志,和13位片偏移。16位标识位能够将分片之前的数据集合到一块,3位标志位可以确保最后一个分片不会被丢包,13位片偏移可以保证数据被有序的组合。
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
上面的五类划分存在一定的局限性,一个B类子网中允许有6万多台主机,而A类更多,实际中一个子网中很少存在那么多的主机的,所以又提出了新的划分方案, 称为CIDR(Classless Interdomain Routing无类域间路由选择)。引入一个额外的子网掩码(subnet mask)来区分网络号和主机号,一个32位的正整数,通常用一串 “0” 结尾。将IP地址和子网掩码进行 “按位与” 操作, 得到的结果就是网络号。网络号和主机号的划分与这个IP地址是A类、B类还是C类无关。
IP地址 | 140.252.20.68 |
---|---|
子网掩码 | 255.255.255.240 |
网络号 | 140.252.20.64 |
子网地址范围 | 140.252.20.64~140.252.20.79 |
CIDR在一定程度上缓解了IP地址不够用的问题,提高了利用率,减少了浪费。但是IP地址的绝对上限并没有增加,仍然不是很够用,这时候有三种方式来解决,分别是动态分配IP地址、NAT技术,IPv6。 动态分配IP地址: 只给接入网络的设备分配IP地址,同一个MAC地址的设备,每次接入互联网中,得到的IP地址不一定是相同的。
- 将IP地址中的主机地址全部设为0, 就成为了网络号,代表当前这个局域网。
- 将IP地址中的主机地址全部设为1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包。
- 127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1
一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到英特网上。私有IP地址包含在这个范围中的,其余的则称为全局IP(或公网IP)
- 10.*,前8位是网络号,共16777216个地址
- 172.16.到172.31.,前12位是网络号,共1048576个地址
- 192.168.*,前16位是网络号,共65,536个地址
一个路由器可以配置两个IP地址,一个是WAN口IP,一个是LAN口IP(子网IP)。路由器LAN口连接的主机, 都从属于当前这个路由器的子网中。不同的路由器, 其子网IP都是一样的(通常都是192.168.1.1)。每一个家用路由器,其实又作为运营商路由器的子网中的一个节点,这样的运营商路由器可能会有很多级,最外层的运营商路由器,WAN口IP就是一个公网IP了。子网内的主机需要和外网进行通信时,路由器将IP首部中的IP地址替换成WAN口IP,这样逐级替换,最终数据包中的IP地址成为一个公网IP。 这种技术叫做NAT(Network Address Translation网络地址转换)。
路由的过程,就是一跳一跳(Hop by Hop) “问路” 的过程。所谓 “一跳” 就是数据链路层中的一个区间,具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间。当IP数据包,到达路由器时,路由器会先查看目的IP。路由器决定这个数据包是能直接发送给目标主机, 还是需要发送给下一个路由器,依次反复,一直到达目标IP地址。
如下图,是一个路由表(route命令可以查看)这台主机有两个网络接口,一个网络接口连到192.168.10.0/24网络,另一个网络接口连到192.168.56.0/24网络。路由表的Destination是目的网络地址,Genmask是子网掩码,Gateway是下一跳地址,Iface是发送接口,Flags中的U标志表示此条目有效(可以禁用某些 条目),G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发。
比如目的地址是192.168.56.3,首先跟路由表的第一行的子网掩码做与运算得到192.168.56.0,与第一行的目的网络地址不符,再跟第二行的子网掩码做与运算得到192.168.56.0,正是第二行的目的网络地址,因此从eth1接口发送出去。192.168.56.0是与eth1接口直接相连的网络。因此可以直接发到目的主机,不需要经路由器转发。 如果目的地址是202.10.1.2依次和路由表前几项进行对比,发现都不匹配,按缺省路由条目,从eth0接口发出去。发往192.168.10.1路由器,由192.168.10.1路由器根据它的路由表决定下一跳地址。