连接概述
顺着第一篇的思路下来,到最后我们已经可以依靠分层达到两台主机之间的自由通信,那么问题来了,假设现在有主机 A(客户端)及主机 B(服务端),其中主机 A 需要访问主机 B 的资源,需要哪几个必要条件呢?经过上篇文章可知至少需要四个条件:
主机A需要具有一个ip地址
主机B需要具有一个ip地址
主机A需要具有一个客户端端口号
主机B需要具有一个服务端端口号
具备上述四个条件后 A 获取 B 的信息是有要求的,根本上的要求是数据信道可靠,就是平时所说的可靠连接,那么如何保证连接的可靠性呢,TCP 协议就是靠确认应答机制、超时重传机制等保证连接可靠性的,接下来就通过 TCP 协议的三次握手及四次(三次)挥手来分析一下 A 与 B 建立连接、关闭连接的技术细节是如何落地实现的。
三次握手
第一次:首先客户端 A 会向服务端 B 发送一个数据同步请求,可以称为建立连接请求 syn,同时客户端 A 的 cpu 内核会为这个 syn 请求生成一个随机的序列号 seq 发送给服务端。此处整体称为第一次握手,注意此处为随机序列号。
第二次:服务端 B 接到客户端 A 发送的 syn 请求后,会回复一个[syn+ack]的响应,其中 syn 仍表达数据同步的意思,这个应答 seq 值由服务端 B 的 cpu 随机生成,ack 的值为第一次握手 seq 的值+1,ack 表示两层含义:
服务端B已经收到了客户端A发过来的数据同步请求
希望客户端接下来的应答消息的seq的值以ack回复的值开始传输。
这个称为第二次握手。
第三次:客户端 A 接收到服务端 B 的[syn+ack]应答消息会给 B 回复一个 ack 应答,ack 消息中 seq 值为第二次握手 ack 的值,而 ack 则为第二次握手的请求的 seq 值+1。
三次握手通信释义图如上所示,接下来我们来通过抓包的形式来看一下实际报文,印证三次握手的报文通信。
笔者通过 wireshark(抓包工具)抓取数据包,采用打开一个浏览器网页的场景模拟对服务器 B 的请求。
第一次握手抓包图如下:
第二次握手抓包释义图如下:
第三次握手抓包释义图如下:
通过三次握手的抓包可以很清晰的展示三次交互流程,可能有人会有连带的疑问,为什么一定是三次,而不是别的次数,这里三次其实是最优的次数,而不是一定的次数,比如如果两次的话 A、B 两方将会有一方无法做出信息是否送达的确认,而超过三次则造成了浪费,因为三次交互中 A、B 都已经对两方应答一次了。接下来来看一下四次挥手的交互流程。
四次挥手
理解三次握手及流程后,四次挥手其实本质和三次握手的确认流程基本上是一样的,下面我们简单梳理一下挥手标准流程。
第一次:当 A 确认当前连接数据已经全部发送完成以后,会发起关闭连接请求,此时 A 不再发送业务报文,发送的请求标志为 FIN ,seq 为 x,此处整体为第一次挥手。
第二次:B 收到 A 发出的关闭连接的请求之后,会给 A 一个确认响应,告诉 A 我收到你关闭连接的请求了,但是我有可能还有没发完的数据需要继续给你发送,响应的标志为 ack,seq 为 Y,ack 为 x+1,此处整体为第二次挥手。
第三次:当 B 把数据传输完之后会发送释放连接响应,此处标志 B 释放连接,不会再发送业务报文,此时请求的标志为 FIN+ack,seq 的值为 y,ack 的值为 x+1,此处整体为第三次挥手。
第四次:A 对 B 第三次挥手做最后确认,并释放连接,此时请求标志为 ack,seq 为 x+1,ack 为 y+1。
四次挥手通信释义图如上所示,由于三次握手的每一次都通过抓包工具详细描述了通信详情,此处挥手抓一个整体包截图,由读者自行解析分析即可。
四次挥手抓包整体释义图如下:
可以看到,这里面的挥手包数与咱们分析的标准流程不一样,这里是因为第二次和第三次挥手都是 B 向 A 发起确认响应,区别是第二次只是确认,因为可能还有数据没有传完,要继续传,全部数据传完后 B 才能发出最后指令进行释放连接,但这时如果发第二次挥手的时候就可以确认没有数据需要再同步给 A 了,这时如果按照标准流程,B 会给 A 发送两个相同的数据包,这样就造成了资源浪费,故这块挥手做了优化,可以确认数据的情况下,可以把第二次和第三次挥手合并成一次,所以此处是三次握手。
小结
本文梳理了 TCP 建立连接概述、三次握手、四次挥手的流程,下一篇将会从控制报文协议 ICMP 及常用网络工具命令 ping、traceroute 为切入点分析控制消息的设计及实现机制,小伙伴们如果对本文有疑问可以留言或者加我微信咨询,大家一起进步。
评论