当前位置:   article > 正文

计算机网络-传输层篇-TCP的三次握手_第三次握手psh可以为1吗

第三次握手psh可以为1吗

目录

首先回顾TCP标记

概述

过程

为什么需要握手这个操作, 能不能不握手?

为什么需要三次握手,两次不行吗?


  • 首先回顾TCP标记

  • 标记 含义
  • URG Urgent:紧急位,URG=1,表示紧急数据
  • ACK Acknowledgement:确认位,ACK=1,确认号才生效
  • PSH Push:推送位,PSH=1,尽快地把数据交付给应用层
  • RST Reset:重置位,RST=1,重新建立连接
  • SYN Synchronization:同步位,SYN=1表示连接请求报文
  • FIN Finish:终止位,FIN=1表示释放连接
  • 概述

  • 三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包
  • 进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备
  • 实质上其实就是连接服务器指定端口,建立TCP连接
  • 并同步连接双方的序列号和确认号,交换TCP窗口大小信息
  • 过程

  • 刚开始客户端处于 Closed 的状态
  • 服务端处于 Listen 状态
  • 进行三次握手:
  • 第一次握手:
  • 客户端给服务端发一个 SYN 报文
  • 并指明客户端的初始化序列号 ISN
  • 此时客户端处于 SYN_SENT(同步已发生) 状态
  • 首部的同步位SYN=1,初始序号seq=x
  • SYN=1的报文段不能携带数据,但要消耗掉一个序号
  • 第二次握手:
  • 服务器收到客户端的 SYN 报文之后
  • 会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN(s)
  • 同时会把客户端的 ISN + 1 作为ACK 的值
  • 表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_RCVD(同步已接收) 的状态
  • 在确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y
  • 第三次握手:
  • 客户端收到 SYN 报文之后,会发送一个 ACK 报文
  • 当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED(建立连接) 状态
  • 服务器收到 ACK 报文之后,也处于 ESTABLISHED(建立连接) 状态
  • 此时,双方已建立起了连接
  • 确认报文段ACK=1,确认号ack=y+1,序号seq=x+1(初始为seq=x,第二个报文段所以要+1)
  • ACK报文段可以携带数据,不携带数据则不消耗序号
  • 发送第一个SYN的一端将执行主动打开(active open)
  • 接收这个SYN并发回下一个SYN的另一端执行被动打开(passive open)
  • 在socket编程中,客户端执行connect()时,将触发三次握手
  • 为什么需要握手这个操作, 能不能不握手?

  • 对比一下 UDP 的通信流程和 TCP 的通信流程
  • 可以发现, 在 UDP 协议中, 是没有握手这个操作的
  • 这里就引出了 TCP 与 UDP 的一个基本区别, TCP 是可靠通信协议, 而 UDP 是不可靠通信协议
  • TCP 的可靠性含义:
  • 接收方收到的数据是完整, 有序, 无差错的
  • UDP 不可靠性含义:
  • 接收方接收到的数据可能存在部分丢失, 顺序也不一定能保证
  • UDP 和 TCP 协议都是基于同样的互联网基础设施, 且都基于 IP 协议实现
  • 互联网基础设施中对于数据包的发送过程是会发生丢包现象的
  • 为什么 TCP 就可以实现可靠传输, 而 UDP 不行?
  • TCP 协议为了实现可靠传输, 通信双方需要判断自己已经发送的数据包是否都被接收方收到
  • 如果没收到, 就需要重发
  • 为了实现这个需求, 很自然地就会引出序号(sequence number) 和 确认号(acknowledgement number) 的使用
  • 发送方在发送数据包(假设大小为 10 byte)时
  • 同时送上一个序号( 假设为 500)
  • 那么接收方收到这个数据包以后, 就可以回复一个确认号(510 = 500 + 10) 告诉发送方 “我已经收到了你的数据包, 你可以发送下一个数据包, 序号从 510 开始”
  • 这样发送方就可以知道哪些数据被接收到,哪些数据没被接收到, 需要重发
  • 为什么需要三次握手,两次不行吗?

  • 已经失效的连接请求报文传送到对方,引起错误
  • 主要原因:
  • 1. 防止重复历史连接的初始化
  • 2.同步双方初始序列号
  • 3.避免资源的浪费
  • 分析:
  • 第一次握手:
  • 客户端发送网络包,服务端收到了
  • 这样服务端就能得出结论:
  • 客户端的发送能力、服务端的接收能力是正常的
  • 第二次握手:
  • 服务端发包,客户端收到了
  • 这样客户端就能得出结论:
  • 服务端的接收、发送能力,客户端的接收、发送能力是正常的
  • 不过此时服务器并不能确认客户端的接收能力是否正常
  • 第三次握手:
  • 客户端发包,服务端收到了
  • 这样服务端就能得出结论:
  • 客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常
  • 因此,需要三次握手才能确认双方的接收与发送能力是否正常
  • 试想如果是用两次握手,则会出现下面这种情况:
  • 如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求
  • 后来收到了确认,建立了连接
  • 数据传输完毕后,就释放了连接
  • 客户端共发出了两个连接请求报文段
  • 其中第一个丢失
  • 第二个到达了服务端
  • 但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端
  • 此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接
  • 不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/547762
推荐阅读
相关标签
  

闽ICP备14008679号