文章目录

  • 1.IP的概念
  • 1.1IP,主机与路由器
  • 1.2IP与TCP的对比
  • 2.IP报头
  • 2.1IP报头格式
  • 2.2各部分作用
  • 2.3IPv4与IPv6
  • 2.4一跳
  • 2.5 8位生存时间
  • 2.6 分片问题
  • 2.6.1分片的方式与原因
  • 2.6.2分片的缺点
  • 2.7 组装问题
  • 2.7.1 16位标识
  • 2.7.2 13位偏移
  • 2.7.3 3位标志
  • 3.网段的划分
  • 3.1网络号与主机号
  • 3.2通信的过程
  • 3.3划分网络号与主机号
  • 3.3.1最初的划分方法
  • 3.3.2CIDR划分
  • 4.特殊的IP地址
  • 5.私有IP和公有IP
  • 5.1 常用的分配IP地址的方法
  • 5.2路由表
  • 5.2.1查看路由表
  • 5.2.2路由表的使用
  • 5.3报文发送过程

1.IP的概念

1.1IP,主机与路由器

IP=网络号+主机号。
主机:配有IP地址,可以进行路由控制的设备。
路由器:配有IP地址,主要进行路由控制的设备。
节点:主机和路由器的统称。

1.2IP与TCP的对比

TCP解决的是数据传输的决策问题,IP则提供了一种能力,即将数据从主机跨网络传送到另一台主机的能力。IP不提供任何可靠性机制。可以理解为IP是一个执行者,而TCP是一个决策者。

2.IP报头

2.1IP报头格式

ip传输报文 java tcp ip报文传输过程_IP

2.2各部分作用

四位首部长度:IP协议中的四位首部长度与TCP中的首部长度的作用一样,可以实现报头与报文的分离,单位也是4个字节,当没有选项的时候,四位首部长度的值为1010。
源IP与目的IP:通过源IP地址和目的IP地址可以得知,IP报文的来源以及交给哪一台主机。
16位总长度:这个总长度是和UDP报文是相同的,表示整个报文的大小,同时也说明IP报文不是面向字节流的,说TCP是面向字节流的,是站在应用层的角度来看待的。
4位版本号:指定IP协议的版本,通常来说是4,表示IPv4。
8位服务类型:3位优先权字段(已经弃用),4位TOC字段和1位保留字段(必须为0),4位TOS分别表示最小延时,最大吞吐量,最高可靠性,最小成本,这四者相互冲突,只能选择一个。对于ssh/telnet这样的应用程序,最小延时比较重要;对于ftp这样的程序,最大吞吐量比较重要。
16位标识:唯一的标识主机发送的报文,如果IP报文在数据链路层被分片了,那么每一个片里面的这个id是相同的。
3位标志字段:第一位保留(保留的意思是限制不用,但是不好说以后会不会用到)。第二位置的为1表示禁止分片,这时候如果报文长度超过MTU,IP模块就会丢弃报文,第三位表示更多分片,如果分片的话最后一个分片置为0,否则为1,类似一个结束标记。
13位分片偏移:是分片相对于原始IP报文开始处的偏移,其实就是在表示当前分片在原报文处在哪个位置,实际偏移的字节数是这个值*8得到的,因此除了最后一个报文之外,其他报文的长度必须是8的整数倍(否则报文就不连续了)。
8位生存时间:数据报到达目的地的最大报文跳数,一般是64,每经过一个路由,TTL-=1,一直减到0还没到达,那么就丢弃了,这个字段主要用来防止出现路由循环。
8位协议:表示上层协议的类型。
16位头部校验和:使用CRC进行校验,来鉴别头部是否损坏。

2.3IPv4与IPv6

IPv6是更高一级的IP版本,但是现在我们使用的基本都是IPv4,全面普及IPv6暂时不现实。只能慢慢地迁移。

2.4一跳

当报文由一个节点交付给下一个节点的时候,称为数据包的一跳。

2.5 8位生存时间

游离报文:当一个报文在进行发送的时候,双方关闭网线,就会形成游离报文。如果游离报文发现网线关闭,就可能被丢弃,但是如果没有发现网线关闭,就有可能在几个节点的环路中来回跳转,每跳转一次都会消耗一定的资源,当网络中积攒了大量游离报文就有可能造成网络的崩溃。
因此引入了8位生存时间,它表示的是一共能够发生几次跳转,当达到跳转上限的时候,报文会自动销毁。

2.6 分片问题

2.6.1分片的方式与原因

因为IP网络层也不是最终要发送报文的一层,发送保卫由下一层即数据链路层来实现。数据链路层规定,一次向网络中发送的报文的大小最大是MTU:1500字节。

那么如果TCP传给IP的数据太多,导致IP报文太大怎么处理呢?注意IP是面向数据报的,而不是面向字节流的。

这个时候就需要将IP报文进行分片操作了,分片之后由对端的IP层来进行组装。

比如IP的数据是3400个字节,此时就需要对此IP报文进行分片操作:

ip传输报文 java tcp ip报文传输过程_子网掩码_02


分片的过程就是将原有的报头提出,作为其中一个子报文的首部,然后将数据分为几个1480部分,并为它们添加报头

这一过程是IP层做的,与传输层无关,传输层也不需要知道。

2.6.2分片的缺点

分片会提高丢包的风险,因为是将报文分几份来进行发送的。如果不想分片是由谁来决定呢?
答案是传输层,因为传输层才是数据发送的控制部分,他可以决定数据什么时候发,发多少的问题。
注意UDP协议的话,如果数据太多,那么只能进行分片,但是如果是TCP协议的话,因为有缓冲区,因此是可以进行控制不分片的。

2.7 组装问题

2.7.1 16位标识

当分片的报文到达对端的时候,就需要进行报文的组装了。此时IP报文中的16位标识开始发挥作用,来源于同一报文的分片报文,它们的16位标识符是一样的,这样就可以进行分堆,比如这一批报文都是来自于一个IP报文分片产生的。

2.7.2 13位偏移

有了16位标识,是远远不够的,因为只能区分哪些报文时一起的,但是无法判断报文的组合顺序。因此需要引入位偏移。它表示的是有效载荷在原始报文有效载荷的偏移量。根据偏移量进行升序排序即可。

ip传输报文 java tcp ip报文传输过程_ip传输报文 java tcp_03


比如将一个IP报文拆分成这三个部分,那么它们的位偏移就分别为0,1480,2960。

2.7.3 3位标志

我们发现,当报文发生了丢失就可以通过偏移量来发现,因为如果首报文丢失或者中间报文丢失,偏移量是连接不上的(每个IP报文都有自己的数据大小,IP报文数据大小+IP报文的偏移量=下一个报文的偏移量)。
但是如果是尾部丢失了呢?该如何查找呢?
因此引入了3位标志,其中1位保留,一位表示禁止分片,最后一位就表示是否有更多的报文,当最后一位为1的话,就表示有更多的报文,如果为0的话就表示没有更多的报文了。

3.网段的划分

3.1网络号与主机号

比如对于192.168.128.10这台主机,它所在的网段号是192.168.128,它的主机号是10。
网络号:保证相互链接的两个网段具有不同的标识。
主机号:同一个网段内,主机之间具有相同的网络号,但是必须有不同的主机号。
同一个网段的两个主机,网段号相同,主机号不同。

3.2通信的过程

ip传输报文 java tcp ip报文传输过程_ip传输报文 java tcp_04


当一台主机想像另一台主机发消息的时候,会首先查看自己的网络号与当前局域网的网络号是否相同,如果不相同,就会到路由器构成的网络中去查找哪个网络号符合条件,找到符合条件的网络号之后,再到该网络号对应的局域网中根据主机号找到对应的主机。

手动为子网内新增的主机分配节点IP地址时很复杂的事情,有一种技术称为DHCP,能够自动的给子网内新增的主机节点分配IP地址,一般路由器都带有DHCP功能·,因此路由器也可以看做一个DHCP服务器。

3.3划分网络号与主机号

3.3.1最初的划分方法

过去曾经提出过一种划分网络号和主机号的方案,把所有的IP分为5类:

ip传输报文 java tcp ip报文传输过程_IP_05


随着网络的发展,大多数组织都申请B类网络地址,这就导致B类的地址很快就分配完了,而A类却浪费了大量地址。

例如申请了一个B类地址,理论上一个子网内能允许6万5千多个主机,A类地址的子网内的主机数更多。
然而在实际的网络中,不会存在一个子网内有这么多的情况,因此大量的IP地址都被浪费掉了。

3.3.2CIDR划分

针对这种情况,提出了新的划分方案,称为CIDR。

引入一个额外的子网掩码,来区分网络号和主机号。
子网掩码也是一个32位的正整数,通常用一串"0"来结尾。
将IP地址和子网掩码进行按位与操作,得到的结果就是网络号。
网络号和主机号的划分与这个IP地址时A类,B类还是C类无关。

总结来说就是:人为定义一个子网掩码,并规定子网掩码从左到右必须是连续的1或者0(通常首位为1),从而根据网段中的主机量来控制网络号和主机号。
举个例子:比如某一个局域网内有256台主机,假设它的网络号被设定为140.252.20.0,那么在该网络的主机的IP范围就是140.252.20.0~140.252.20.255,正好256台。其中每一台主机按位与上该局域网的子网掩码都可以得到网络号,此时子网掩码的值是255.255.255.0。
还有一种更加简洁的表示方式:140.252.20.68/24表示的是IP地址为140.252.20.68,并且子网掩码的高24位时1,即255.255.255.0

4.特殊的IP地址

将IP地址中的主机地址都设为0,就变成了网络号,代表整个局域网。
将IP地址中的主机地址全部设为1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包。
127.*的地址用于本机轮回测试,通常是127.0.0.1

5.私有IP和公有IP

5.1 常用的分配IP地址的方法

IP地址是一个4字节32位的正整数,那么一共只有2的32次方个IP地址,大概是43亿左右,而TCP/IP协议规定所有主机都要有IP地址,这就会出现僧多粥少的情况。虽然我们使用了CIDR划分,但是治标不治本,32位的IP是不能改变的。
因此我们使用三种方式来分配IP地址:

1.动态分配IP地址,当一个设备接入网络之后,再为其分配IP地址,不过对于我们购买的云服务器来说,IP地址基本是一个。
2.NAT技术。
3.IPv6:IPv6不是IPv4的升级版,这是两个无关的协议,IPv6使用16个字节128位表示一个IP地址,但是IPv6还没有普及。
4.IP地址的复用(即公有IP和私有IP),下面来详细介绍。

ip传输报文 java tcp ip报文传输过程_IP_06


在整个的大网络中,我们会发现,不同的局域网中可以有相同IP的主机。同时我们会发现一个路由器有两份IP地址。这是因为路由器是横跨两个网段的,它可以是该局域网的一部分(网络号和局域网一致),也可以作为一台主机和外面的其他路由器共同构成一个局域网(网络号与更大的局域网一致)。

5.2路由表

5.2.1查看路由表

当路由器收到IP报文的时候,该如何处理呢?通过查看路由表来判断IP报文的下一跳在哪里。

任意一个节点都有路由表(主机也可以)。
一个路由器至少有两个IP地址,也可以有多个。

我们可以通过route命令来查看我们主机的路由表:

ip传输报文 java tcp ip报文传输过程_子网掩码_07

Destination:目标子网号。
Geteway:目标路由器。
Genmask:子网掩码。
Flags:U表示正在被使用,G表示路由器。没有G表示目的网络地址时与本机直接相连的网络,不必经过路由转发。
Iface:表示接口。

5.2.2路由表的使用

当路由器收到报文的时候,会将其目的IP与各子网掩码做按位与,得到的网络号与Destination作比较:
1.如果相等,则通过接口Iface将其发送到对应网段的同一接口的主机(路由器)上(接口的另一端),再进行路由查询。
2.当网络号与所有的Destination都不同的时候,进行路由器就会将报文丢给默认路由器,也称为默认下一跳,即Destination为default所对应的IP地址,它表示的是一个路由器。
注意,默认路由器都是运营商自己设定好了的,通过路由器一定能最终到达目标网络。

5.3报文发送过程

报文发送的过程其实就是一个不断进行路由查询的过程,当找到对应网段之后(即子网掩码与目的IP按位与得到的网络号与该网段的网络号相等)则进入内网,通过IP地址找到对应的主机。