TCP/IP是传输控制协议和网络协议的简称,它定义设备如何连入因特网,以及数据如何在他们之间传输的标准。TCP/IP不是一个协议,而是一个协议族的统称,里面包括了IP协议、ICMP协议、TCP协议、以及http、ftp、pop3协议等,网络计算机都采用这套协议族进行互联。提到网络协议栈结构,最著名的当属 OSI 七层模型,但是 TCP/IP 协议族的结构则稍有不同,它们之间的层次结构有如图对应关系:
从上图可见,根据TCP/IP四层模型,其中各层的任务如下:
在日常使用中,我们使用TCP/IP的场景一般如下图所示:
其对应的数据流向如下图所示:
当应用程序发送数据的时候,程序调用更低一层的接口,每一层都会对原有数据增加一些首部或尾部信息。最终通过以太网传送给对端的设备,对端设备通过相反的操作对首部和尾部信息进行剥离后,就成了用户需要处理的业务数据。接下来我们将使用到的协议从下往上(链路层、网络层(IP、ARP、ICMP和IGMP)、传输层(UDP和TCP))进行分别介绍。
通过上面示意图可知,网络层传送下来的IP数据报需要在数据链路层进行封装之后发送到对端设备上。
接下来我们将详细介绍链路层。
由于物理层的线路有传输介质与通信设备组成,比特流在传输介质上传输时肯定会存在误差的。引入了链路层之后,就可以采用一些手段,向网络层提供高质量的数据传输服务。比如对于网络层,由于链路层的存在,而不需要关心物理层具体采用了那种传输介质和通信设备。
封装成帧(framing)就是在一段数据的前后分别添加首部和尾部,然后就构成了一个帧。首部和尾部的一个重要作用就是进行帧定界(确定帧的界限)一般为0x7E。
MAC 层为 LLC 和 OSI 网络的上层提供了物理层的抽象。
IP 协议位于网络层,它是 TCP/IP 协议族中最为核心的协议,所有的 TCP、UDP、ICMP 及 IGMP 数据都以 IP 数据报格式传输。IP 协议提供的是不可靠、无连接的数据报传送服务。
IP数据报的格式:
如上图所示,普通的 IP 数据报的报头长度 20 字节(除非有选项字段),各个部分的作用:
为了便于寻址以及层次化构造网络,每个 IP 地址可被看作是分为两部分,即网络号和主机号。同一个区域的所有主机有相同的网络号(即 IP 地址的前半部分相同),区域内的每个主机(包括路由器)都有一个主机号与其对应。
IP 地址被分为 A、B、C、D、E 五类:
B 类地址:
C 类地址:
IP 地址如果只使用 ABCDE 类来划分,会造成大量的浪费:一个有 500 台主机的网络,无法使用 C 类地址。但如果使用一个 B 类地址,6 万多个主机地址只有 500 个被使用,造成 IP 地址的大量浪费。因此,可以在 ABC 类网络的基础上,进一步划分子网:占用主机号的前几个位,用于表示子网号。这样 IP 地址就可看作 IP = 网络号 + 子网号 + 主机号。子网号的位数没有硬性规定,于是我们用子网掩码来确定一个 IP 地址中哪几位是主机号,具体使用方法如图:
如果发送方与接收方直接相连(点对点)或都在一个共享网络上(以太网),那么 IP 数据报就能直接送达。而大多数情况则是发送方与接收方通过若干个路由器(router)连接,那么数据报就需要经过若干个路由器的转发才能送达,它是怎么选择一个合适的路径来"送货"的呢?IP 层在内存中有一个路由表(输入命令 route -n 可以查看路由表),当收到一份数据报并进行发送时,都要对该表进行搜索:
当你用 ifconfig 查看 IP 地址时,有时你会发现自己的 IP 地址是这样的———192.168.X.X 或172.16.X.X。这是 C 类网和 B 类网的私有地址,就是俗称的内网 IP。这是因为你的路由器采用了 NAT 技术。NAT(Network Address Translation,网络地址转换)是 1994 年提出的。当在专用网内部的一些主机本来已经分配到了内网 IP 地址,但现在又想和因特网上的主机通信时,NAT 技术将其内网 IP 地址转换成全球 IP 地址,然后与因特网连接,也就是说,内网的数台主机使用了同一个全球 IP 地址在上网。NAT 技术实现了宽带共享,而且有助于缓解 IP 地址空间枯竭的问题。
网络层不仅有 IP 协议,还有其它如 ARP、ICMP、IGMP、RARP 等其它协议,这一节我们将对这些协议做介绍。
ARP(Address Resolution Protocol,地址解析协议)是将IP地址解析为以太网MAC地址(或称物理地址)的协议。在局域网中,当主机或其它网络设备有数据要发送给另一个主机或设备时,它必须知道对方的网络层地址(即IP地址)。但是仅仅有IP地址是不够的,因为IP数据报文必须封装成帧才能通过物理网络发送,因此发送站还必须有接收站的物理地址,所以需要一个从IP地址到物理地址的映射。APR就是实现这个功能的协议。
ARP报文分为ARP请求和ARP应答报文,报文格式如图所示。
假设主机A和B在同一个网段,主机A要向主机B发送信息。如下图所示:
具体的地址解析过程如下:
当主机A和主机B不在同一网段时,主机A就会先向网关发出ARP请求,ARP请求报文中的目标IP地址为网关的IP地址。当主机A从收到的响应报文中获得网关的MAC地址后,将报文封装并发给网关。如果网关没有主机B的ARP表项,网关会广播ARP请求,目标IP地址为主机B的IP地址,当网关从收到的响应报文中获得主机B的MAC地址后,就可以将报文发给主机B;如果网关已经有主机B的ARP表项,网关直接把报文发给主机B。
设备通过ARP解析到目的MAC地址后,将会在自己的ARP表中增加IP地址到MAC地址的映射表项,以用于后续到同一目的地报文的转发。ARP表项分为动态ARP表项和静态ARP表项。
动态ARP表项由ARP协议通过ARP报文自动生成和维护,可以被老化,可以被新的ARP报文更新,可以被静态ARP表项覆盖。当到达老化时间、接口down时会删除相应的动态ARP表项。
静态ARP表项通过手工配置和维护,不会被老化,不会被动态ARP表项覆盖。配置静态ARP表项可以增加通信的安全性。静态ARP表项可以限制和指定IP地址的设备通信时只使用指定的MAC地址,此时攻击报文无法修改此表项的IP地址和MAC地址的映射关系,从而保护了本设备和指定设备间的正常通信。静态ARP表项分为短静态ARP表项和长静态ARP表项。
免费ARP报文是一种特殊的ARP报文,该报文中携带的发送端IP地址和目标IP地址都是本机IP地址,报文源MAC地址是本机MAC地址,报文的目的MAC地址是广播地址。设备通过对外发送免费ARP报文来实现以下功能:
使能了免费ARP报文学习功能后,设备会根据收到的免费ARP报文中携带的信息(源IP地址、源MAC地址)对自身维护的ARP表进行修改。设备先判断ARP表中是否存在与此免费ARP报文源IP地址对应的ARP表项:
关闭免费ARP报文学习功能后,设备不会根据收到的免费ARP报文来新建ARP表项,但是会更新已存在的对应ARP表项。如果用户不希望通过免费ARP报文来新建ARP表项,可以关闭免费ARP报文学习能,以节省ARP表项资源。
定时发送免费ARP功能可以及时通知下行设备更新ARP表项或者MAC地址表项,主要应用场景如下:
由于用户可以设定VRRP虚拟IP地址和MAC地址对应关系,因此有以下两种情况:
如果ARP请求是从一个网络的主机发往同一网段却不在同一物理网络上的另一台主机,那么连接它们的具有代理ARP功能的设备就可以回答该请求,这个过程称作代理ARP(Proxy ARP)。代理ARP功能屏蔽了分离的物理网络这一事实,使用户使用起来,好像在同一个物理网络上。代理ARP分为普通代理ARP和本地代理ARP,二者的应用场景有所区别:
关于ARP的详细内容可以参考文章:ARP技术介绍
IGMP是Internet Group Management Protocol(互联网组管理协议)的简称。它是TCP/IP协议族中负责IP组播成员管理的协议,用来在IP主机和与其直接相邻的组播路由器之间建立、维护组播组成员关系。
到目前为止,IGMP有三个版本:
IGMPv1主要基于查询和响应机制来完成对组播组成员的管理。
当一个网段内有多台组播路由器时,由于它们都能从主机那里收到IGMP成员关系报告报(Membership Report Message),因此只需要其中一台路由器发送IGMP查询报文(Query Message)就足够了。这就需要有一个查询器(Querier)的选举机制来确定由哪台路由器作为IGMP查询器。对于IGMPv1来说,由组播路由协议(如PIM)选举出唯一的组播信息转发者DR(Designated Router,指定路由器)作为IGMP查询器。
如上图所示,假设Host B与Host C想要收到发往组播组G1的组播数据,而Host A想要收到发往组播组G2的组播数据,那么主机加入组播组以及IGMP查询器(Router B)维护组播组成员关系的基本过程如下:
IGMPv1没有专门定义离开组播组的报文。当运行IGMPv1的主机离开某组播组时,将不会向其要离开的组播组发送报告报文。当网段中不再存在该组播组的成员后,IGMP路由器将收不到任何发往该组播组的报告报文,于是IGMP路由器在一段时间之后便删除该组播组所对应的组播转发项。
与IGMPv1相比,IGMPv2增加了查询器选举机制和离开组机制。
i)查询器选举机制
在IGMPv1中,当某共享网段上存在多个组播路由器时,由组播路由协议(如PIM)选举的指定路由器充当查询器。
在IGMPv2中,增加了独立的查询器选举机制,其选举过程如下:
而在IGMPv2中,当一个主机离开某组播组时:
IGMPv3在兼容和继承IGMPv1和IGMPv2的基础上,进一步增强了主机的控制能力,并增强了查询和报告报文的功能。
i)主机控制能力的增强
IGMPv3增加了针对组播源的过滤模式(INCLUDE/EXCLUDE),使主机在加入某组播组G的同时,能够明确要求接收或拒绝来自某特定组播源S的组播信息。当主机加入组播组时:
ii) 查询和报告报文功能的增强
1)携带源地址的查询报文
IGMPv3不仅支持IGMPv1的普遍组查询和IGMPv2的特定组查询,而且还增加了对特定源组查询的支持:
2)包含多组记录的报告报文
IGMPv3报告报文的目的地址为224.0.0.22,可以携带一个或多个组记录。在每个组记录中,包含有组播组地址和组播源地址列表。组记录可以分为多种类型,如下:
关于IGMP文章详细内容,请参考:IGMP技术介绍
通信过程中发生各种问题时,ICMP 将问题反馈,通过这些信息,管理者可以对所发生的问题作出诊断,然后采取适当的措施去解决它。CMP 报文由 8 位错误类型、8 位条件代码和 16 位校验和组成,被封装在一个 IP 数据报中:
主机中常常有多个应用进程同时在与外部通信(比如你的浏览器和 QQ 在同时运行),下图中,A 主机的 AP1 进程在与 B 主机的 AP3 进程通信,同时主机 A 的 AP2 进程也在与 B 主机的 AP4 进程通信。两个主机的传输层之间有一个灰色双向箭头,写着“传输层提供应用进程间的逻辑通信”。
看起来数据似乎是沿着双向箭头在传输层水平传输的,但实际上是沿图中的虚线经多个协议层次而传输。
从上图中,AP1 与 AP3 的通信与 AP2 与 AP4 的通信可以使用同一个传输层协议来传输(TCP或UDP),根据 IP 地址或 MAC 地址都只能把数据传到正确的主机,但具体需要传到哪一个进程,是通过端口来辨认的。比如同时使用浏览器和 QQ,浏览器占用 80 端口,而 QQ 占用 4000 端口,那么发送过来的 QQ 消息便会通过 4000 端口显示在 QQ 客户端,而不会错误地显示在浏览器上。
端口号有 0 ~ 65535 的编号,其中:
UDP(User Datagram Protocol)用户数据报协议,它只在 IP 数据报服务之上增加了很少一点功能,它的主要特点有:
UDP 数据报可分为两部分:UDP 报头和数据部分。其中数据部分是应用层交付下来的数据。UDP 报头总共 8 字节,而这 8 字节又分为 4 个字段:
UDP报文抓包数据如下:
我们知道 UDP 报头一共 8 字节,所以从 eb39 到 ac82 是 UDP 报头的部分。
TCP 和 UDP 处在同一层——传输层,但是它们有很多的不同。TCP 是 TCP/IP 系列协议中最复杂的部分,它具有以下特点:
TCP 是面向字节流的,而 TCP 传输数据的单元是 报文段 。一个 TCP 报文段可分为两部分:报头和数据部分。数据部分是上层应用交付的数据,而报头则是 TCP 功能的关键。TCP 报文段的报头有前 20 字节的固定部分,后面 4n 字节是根据需要而添加的字段。如图则是 TCP 报文段结构:
20 字节的固定部分,各字段功能说明:
下图是TCP报文抓包数据:
其实输出结果中还包含着 TCP 协议的报文,试着回顾一下,相信你能很快找到哪部分是 IP 协议的首部。IP 报文头紧接着的一部分就是 TCP 报文头,从 170d 开始。
刚才说过,TCP 是面向连接的,在传输 TCP 报文段之前先要创建连接,发起连接的一方被称为客户端,而响应连接请求的一方被称为服务端,而这个创建连接的过程被称为三次握手:
至此 TCP 连接已经建立,客户端进入 ESTABLISHED(已建立连接)状态,当服务端收到确认后,也进入 ESTABLISHED 状态,它们之间便可以正式传输数据了。
当传输数据结束后,通信双方都可以释放连接,这个释放连接过程被称为释放连接:
注意此时连接还没有释放,需要时间等待状态结束后连接两端才会 CLOSED。设置时间等待是因为,有可能最后一个确认报文丢失而需要重传。
上图中展示了三次握手的过程。红色为第一次,黄框是第二次,绿框是第三次,试着根据上面介绍的握手过程来对照 seq 和 ack 值的变化。
可见超时重发机制是 TCP 可靠性的关键,只要没有得到确认报文段,就重新发送数据报,直到收到对方的确认为止。
TCP 规定,接收者收到数据报文段后,需回复一个确认报文段,以告知发送者数据已经收到。而发送者如果一段时间内(超时计时器)没有收到确认报文段,便重复发送。
为了实现超时间重传,需要注意:
连续 ARQ 协议:
也许你也发现了,按上面的介绍,超时重传机制很费时间,每发送一个数据报都要等待确认。在实际应用中的确不是这样的,真实情况是,采用了流水线传输:发送方可以连续发送多个报文段(连续发送的数据长度叫做窗口),而不必每发完一段就停下来等待确认。实际应用中,接收方也不必对收到的每个报文都做回复,而是采用累积确认方式:接收者收到多个连续的报文段后,只回复确认最后一个报文段,表示在这之前的数据都已收到。这样,传输效率得到了很大的提升。
由于接收方缓存的限制,发送窗口不能大于接收方接收窗口。在报文段首部有一个字段就叫做窗口(rwnd),这便是用于告诉对方自己的接收窗口,可见窗口的大小是可以变化的。那么窗口的大小是如何变化的呢?TCP 对于拥塞的控制总结为“慢启动、加性增、乘性减”,如图所示:
参考资料:
《ARP技术介绍 http://www.h3c.com/cn/d_200812/623583_30003_0.htm》
《TCP IP 网络协议基础入门 https://www.lanqiao.cn/courses/98》
《IGMP技术介绍 http://www.h3c.com/cn/d_200805/605837_30003_0.htm》