计算机网络 | TCP 三次握手四次挥手 |半关闭连接

本来是不愿意写的,可是在实际场景,对具体的描述标志还是模糊不清,基础不扎实,就得承认!!!

TCP 连接建立需要解决三大问题:

  1. 知道双方存在
  2. 约定一些参数,如最大滑动窗口值、是否使用滑动窗口扩大选项、时间戳、服务质量等等
  3. 双方能够对运输实体资源(缓存大小、连接表中的项目)进行分配

三次握手

握手: TCP客户端和服务器之间进行交换三个TCP报文段

  1. 初始状态:两端的进程都处于关闭状态
  2. 服务器端创建传送控制块,用来存储TCP连接中的一些重要信息(TCP连接表、指向发送和接收缓存的指针、指向重传队列的指针、当前发送和接收序号等等),之后准本接收TCP客户进程的连接请求。TCP服务器处于监听状态 ,等待客户端进程的连接请求(TCP服务器是被动等待TCP客户进程的连接请求)(这又叫被动打开连接,不是主动建立连接的)
  3. TCP客户进程首先创建传输控制块 (请求发送和接收缓存的指针、指向重传队列的指针、当前的发送和接收序号)
  4. 开始第一次握手,TCP客户进程发送TCP请求报文段,进入同步已发送状态(SYN-SENT),发送的请求报文段中首部的同步位 (SYN = 1),序号字段(seq = x,作为TCP客户进程所选择的初始序号)(注意TCP规定,SYN被设置为1的报文段不能携带数据,但是要消耗一个序号**)(主动打开连接
  5. 第二次握手(前提是服务进程接收客户进程的连接请求),TCP服务进程向TCP客户进程发送连接请求确认报文段(进入同步已接收状态, 监听状态--> 同步已接收状态)(连接请求报文段中头部SYN = 1,ACK = 1, seq = y, ack = x + 1) (同步位SYN = 1,确认位ACK = 1,这可以确定这是连接请求确认报文段) 序号字段 seq = y(初始值设置为y,作为TCP服务器进程所选择的初始序号,确认字段ack = x + 1,这是对TCP客户进程所选择的初始序号的确认),注意,这次发送的报文段(第二次握手)也不能发送数据,同样消耗一个序号
  6. 第三次握手(前提是TCP客户进程收到TCP请求确认报文段),接着TCP客户进程向TCP服务进程发送一个普通 的TCP确认报文段。此时客户进程进入连接已建立状态 ,该发送的普通报文段中,确认位ACK = 1(这表明这是一个普通的TCP确认报文段),序号字段seq = x +1,确认字段ack = y +1(这是对TCP服务进程所选择的初始序号的确认)。(注意,这里的序号为x + 1 ,就是第一次握手发送的报文段是消耗了一个序号,然后TCP规定普通报文段是可以传输数据的,如果不携带数据这不消耗序号,在不携带数据的情况下,下一个数据报文段的序号仍然是x + 1)。TCP服务进程接收到该报文段后也进入了连接已建立状态
  7. 接下来就可以进行可靠的数据传输。

为什么还要发送一个普通的TCP确认报文段呢????===>能够两次握手建立连接???

特殊情境:TCP客户进程发送的请求报文段发送到了TCP服务端进程,但用了很长时间,所以会引发该报文段的超时重传,然后重传的报文段被TCP服务进程正常接收(注意后来发送的超时重传的报文段反而先被接收)然后地第二次握手。注意如果这是两次握手。然后TCP服务进程就进入了连接已建立状态(而不是三次握手进入同步已接收状态。这个时候TCP服务进程会等待TCP客户进程发送TCP连接请求确认报文段的普通确认报文段),第二次握手,没有给TCP发送普通 报文段,进入了连接已建立状态。此时两两可以开始传输数据。开始传输数据了哈,然后传输的数据很少,然后很快就断开连接,两端断开连接后,这时变态的事情就发生了,TCP服务线程接收到第一次发送的TCP连接请求报文段(TCP服务线程进入的连接已建立状态)。然后TCP服务线程肯定会发送确认报文段嘛,搞笑的事情就发生了,TCP客户线程就会莫名奇怪。明明断开连接之后,我啥也没干呀!!!(不理睬,关闭状态)

四次挥手

数据传输结束后,双方都可以释放连接

释放连接前的状态都是 连接已建立(EDTABLISHED)

  1. 假设是TCP客户进程的应用进程通知其主动关闭TCP连接。TCP客户进程发送TCP连接释放报文段,接着TCP客户进程主动关闭状态,进入终止等待1状态(FIN-WAIT-1),该发送的连接释放报文段中的头部终止位FIN = 1,确认位ACK = 1。可以通过这些头部字段信息判定这是TCP连接释放报文段(因为有时候抓包,需要确认什么什么是什么什么包)。同时,对之前收到的报文段确认 seq = u,ack = v。(u -1 , v - 1 分别表示什么 可以参照TCP三次握手)(注意:TCP规定终止位FIN = 1的报文段即使不携带数据,也要消耗一个序号
  2. TCP服务进接收到发送的连接释放报文段后,会发送一个普通的TCP确认报文段,ACK = 1,seq = v , ack = u + 1(还是解释以下吧,seq = TCP服务进程之前已经传送的数据的最后一个字节序号加1),--->关闭等待状态 (CLOSE-WAIT),同时TCP服务进程通知高层应用进程,TCP客户进程要和我们断开TCP连接,请做好断开连接的准备。注意这时,TCP客户进程到TCP服务进程这个方向(--->)的连接就释放了。这时的TCP连接也叫做半关闭状态 。(怎么个半关闭呢?TCP客户进程已经没有发数据给TCP服务进程,但是要注意这个时候TCP服务进程还可以发送数据给TCP客户进程。虽然在TCP服务这边,服务进程已经传达断开消息给高层应用了,但是这段时间内,高层应用是可以继续发送消息的,简言之TCP服务线程可以发送数据给TCP客户线程,并且TCP客户线程是可以接受到发送过来的数据)。TCP客户进程接收到TCP确认报文段后就进入终止等待2状态(FIN-WAIT-2)
  3. TCP服务应用进程知晓后,也就会通知TCP服务进程没有数据要发送,接着TCP服务进程就会发送连接释放报文段(报文段首部FIN = 1 ACK = 1 ,seq = w , ack = u + 1 所以期间发送的报文段次数为w - v 注意 u + 1 是对之前收到的TCP连接释放报文段的重复确认。也就是TCP客户线程第一次发送的报文段的确认)给TCP客户线程。TCP服务这边是被动关闭连接,TCP服务线程发送TCP连接释放报文段后,其状态---->最后确认 (LAST-ACK)
  4. TCP客户线程 接收到发送的报文段后,紧接着发送TCP普通确认报文段 ACK = 1, seq = u + 1, ack = w + 1。之后TCP客户端进入时间等待状态 发送的报文段消耗一个序号。TCP 服务线程接收到该报文段后进入关闭状态(CLOSED),注意TCP客户线程需要经过2MSL时间后才能进入关闭状态。

解释:MSL 最长报文段寿命 RFC793建议为2分钟
思考为什么TCP客户线要经历2MSL的时间自动关闭连接,置为关闭状态呢?

分析,如果TCP客户端发送TCP普通确认报文段后直接置为关闭状态,但是这个报文段很遗憾没有发送成功,在半路丢失。在TCP服务线程触发超时重传,又进行第三次挥手。但是TCP客户线程已经下线了,怎么也连不上,那这就是没有关闭成功。(怎么算的2MSL ??TCP客户线程 发送过去,触发超时,TCP服务线程发送报文段,两倍2MSL)

引申 保活计时器

相关推荐
明天…ling2 小时前
Web前端开发
前端·css·网络·前端框架·html·web
温有情2 小时前
UDP_SOCKET编程实现
网络·网络协议·udp
fqsword2 小时前
计算机网络分类
计算机网络
MonkeyKing_sunyuhua2 小时前
安装 `privoxy` 将 Socks5 转换为 HTTP 代理
网络
pemper_2 小时前
数据不出境------IP证书申请
网络·网络协议·tcp/ip·http·https·ssl
Jack黄从零学c++3 小时前
自制网络连接工具(支持tcpudp,客户端服务端)
linux·c语言·开发语言·网络协议·tcp/ip·udp·信息与通信
网络研究院3 小时前
大型语言模型 (LLM) 劫持攻击不断升级,导致每天损失超过 100,000 美元
网络·人工智能·安全·语言模型·攻击·劫持
网络研究院4 小时前
企业急于采用人工智能,忽视了安全强化
网络·人工智能·安全·工具·风险·企业
mingzhi614 小时前
应届生必看 | 毕业第一份工作干销售好不好?
网络·web安全·面试
白帽黑客cst4 小时前
网络安全(黑客技术) 最新三个月学习计划
网络·数据结构·windows·学习·安全·web安全·网络安全