【彻底搞懂 TCP三次握手、四次挥手 】此篇博客

本文深入探讨TCP协议的连接管理,包括面向连接的特点、TCP连接的端点概念、报文段首部格式以及连接的建立与释放。详细解析了TCP的三次握手过程和四次挥手过程,解释了为何需要三次握手以及在四次挥手后A方要等待2MSL的原因,旨在帮助读者理解TCP连接的可靠性与效率。
摘要由CSDN通过智能技术生成

对于TCP的三次握手和四次挥手,此篇博客由易到难介绍,我用心去写博客,认真看一遍,我相信是受益匪浅的!

一、TCP最主要特点

1.TCP是面向连接的运输层协议

  • 这就是说,应用进程在使用TCP协议之前,必须先建立TCP连接。在传送数据完毕后,必须释放已经建立的TCP连接。通俗点:应用进程之间的通信就像“打电话”,通话前拨号建立连接,通话结束挂机释放

2.每一条TCP连接的只能是两个端点,每一条TCP连接只能是点对点的

  • (什么是端点,点对点连接,下面我会专门讲解)

3.TCP提供可靠的交付服务

  • 也就是说,通过TCP连接传送的数据,无差错、不丢失、不重复、并且顺序到达

4.TCP提供全双工通信

  • TCP允许通信双方应用进程在任何时候都可以发送数据。TCP连接的两端都设有发送和接受数据的缓存,用来临时存放双向通信的数据。在发送数据时,应用程序在把数据发送到TCP缓存后,就可以做自己的事去了,而TCP在合适的时候会把数据放出去。在接收时候,TCP会把接受的数据放入缓存,上层应用进程在合适时候读取缓存中数据。

5.面向字节流

  • TCP中的”流“指的是流入进程或者从进程流出的字节序列。“面向字节流”的含义是:虽然应用程序和TCP的交互式一次一个数据块(大小不等),但是TCP把应用进程交下来的数据仅仅看成一连串的无结构的字节流
    在这里插入图片描述
二、TCP连接

TCP把连接看成最基本的抽象。TCP许多特性都和TCP面向连接有关。所以我们对TCP连接要有更清楚了解。

  • 前面我们说过TCP连接的有两个端点。那么,TCP端点是什么呢?不是主机,不是主机IP地址,不是应用进程。TCP连接的端点叫做套接字或者插口。定义:端口号拼接到IP地址即构成了套接字。因此套接字的表示方法是在点十进制的IP地址后面写上端口号,中间用冒号或者逗号隔开。例如,若IP地址是:192.3.4.5 而端口号是:80,那么套接字就是:192.3.4.5:80,总之,我们有:套接字 socket = (IP地址:端口号)
  • 每一条TCP连接的唯一的被通信两端的两个端点所确定。即:TCP连接 ::={socket1,socket2}={(IP1:port1),(IP2:port2)},这里的IP1和IP2分别是两个端点主机的IP地址,而port1和port2分别是两个端点主机中的端口号。TCP连接的两个套接字就是socket1和socket2
三、TCP报文段的首部格式
  • TCP虽然是面向字节流的,但是传送的数据单元确是报文段。一个TCP报文段分为首部和数据两部分,而TCP的全部功能都体现在它的首部中各字段的作用。因此只有搞清TCP首部个字段的作用,才能掌握TCP的工作原理。下面就讨论TCP报文段的首部格式
  • TCP报文段首部前20字节是固定的,后面4N字节是根据需要而增加的选项(N是整数)。因此TCP首部最小长度是20字节。
    在这里插入图片描述

首部固定部分各字段的意义如下:

  • 1、源端口和目的端口:各占 2 字节,分别写入源端口号和目的端口号
  • 2、序号 :占 4 字节。序号范围是[0,2^32-1]共 2^32个序号。TCP是面向字节流的。在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。整个要传送的字节流起始序号必须在连接建立时设置。首部中的序号字段则指的是本报文段所发送的数据的第一个字节的序号。例如,一个报文的序号字段值是301,而携带数据总共有100字节。这就表明:本报文段的数据第一个字节的序号是301,最后一个字节的序号是400.显然,下一个报文段(如果还有的话)的数据应该从401开始,即下一个报文段的序号值应为401.这个字段名称也叫“报文段序号”
  • 3、确认号:占 4 字节,期望往对方下一次报文段的第一个数据字节的序号。例如:B 正确收到了 A 发送过来的一个报文段,其序号字段值是 501 ,而数据长度是 200 字节(序号 501 ~700),这表明 B 正确收到了 A 发送的到序号 700 为之的数据。因此 B 期望的下一次收到的数据序号是 701 ,于是在 B 发送给 A 的确认报文段中把确认号值为 701。
  • 4、数据偏移:占 4 字节,它指出TCP报文段数据的起始位处距离TCP报文段的起始位置有多远。这个字段实际上指出的就是TCP报文段的首部长度。由于首部有中长度不确定的字段,因此数据偏移是很有必要的。“数据偏移”的单位是 32 位字(及就是 4 字长的字为计算单位)。由于 4 位二进制能够表示的最大十进制是 15 ,因此数据偏移的最大值 60 字节
  • 5、保留:占 6 位,保留为今后使用,但目前应置为 0
  • 6、紧急URG:当URG = 1,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据),而不是按照原来的顺序来传送。怎么实现的:当URG = 1时,发送应用进程就告诉发送方的TCP有紧急数据要传送。于是发送方TCP就把紧急数据插入到本报文段数据的最前面。而在紧急数据后面仍是普通数据。这时要与首部中紧急指针字段配合使用
  • 7、确认 ACK:仅当 ACK = 1 确认号字段才有效。当 ACK = 0 时,确认号无效。TCP规定:在连接建立后,所有的传送报文段都必须把 ACK 值为 1
  • 8、同步 SYN:在连接建立时,用来同步序号。当 SYN = 1 而 ACK = 0 时,表明这是一个连接请求报文段。对方若同意建立连接,则应当响应报文段中使 SYN = 1 和 ACK = 1 。因此 SYN 值为 1 就表示这是一个请求连接的或连接接受报文。
  • 9、推送 PSH:当两个引用进程进行交互式的通信时,又是在一端的应用进程希望在输入一个命令后立即就能够让对方响应。在这种情况下,TCP 就可以使用推送(push)操作。这时,发送方 TCP 把 PSH 置为 1,并立即创建一个报文段发送出去。接收方 TCP 收到了 PSH = 1的报文段,就尽快的交付给接收应用进程,而不再等到整个缓存都填满了后再向上交付
  • 10、复位 RST :当RST = 1 时,表明 TCP 连接中出现严重错误(如:主机崩溃),必须释放连接,然后再重新建立运输连接。RST 置为 1 还用来拒绝一个非法报文段或者拒绝一个连接
  • 11、终止 FIN:用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据发送完毕,并要求释放运输链接
  • 12、窗口:占用 2 字节.窗口值是[0,2^16-1] 之间的整数。窗口指的是发送本报文段的一方的接收窗口。窗口值告诉对方:从本报文字段的首部中的确认号算起,接收放目前允许对方发送的数据量。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。总之,窗口值作为接收方让发送方设置其发送窗口的依据
  • 13、检验和:占 2 字节。检验和字段检验的范围包括首部和数据两个部分。在计算检验和时,要在TCP报文段的前面加上 12 字节的伪首部。
  • 14、紧急指针:占 2 字节。紧急指针仅在 URG = 1 时才有意义,它指出本报文段中的紧急数据的字节数。因此紧急指针指出了紧急数据的末尾在报文段中的位置。当所有紧急数据都处理完时,TCP 就告诉应用程序恢复正常操作。并且,即使窗口为零时也可以发送紧急数据
四、TCP运输连接管理

TCP是面向连接的协议。运输连接是用来传送 TCP报文的。TCP连接的建立采用客户服务器方式。主动发起连接建立的应用叫做客户,而被动等待等待连接的应用进程叫做服务器

4.1 TCP的连接建立

下图画出了 TCP 的建立连接的过程。假定主机 A 运行的是TCP客户程序,而 B 运行 TCP 服务器程序。最初两端的 TCP 进程都处于 CLOSED(关闭状态)。A主动打开连接,而B被动打开连接
在这里插入图片描述
下面就是三次握手的过程

  • 1、B 的TCP 服务器进程先创建 传输控制块 TCB(存储了每一个连接中的重要信息,如: TCP 连接表,到发送和接收缓存的指针,当前的发送和接受的序号),准备接受客户端进程的连接请求。然后服务器进程就会处于 LISTEN (收听)状态,等待客户的连接请求
  • 2、A 的 TCP 客户进程也是先创建 传输控制模块 TCB,然后向 B 发送连接请求报文段,这时首部中的同步位 SYN = 1,同时选择一个初始序号 seq = x 。TCP规定,SYN 报文段(SYN = 1 的报文段)不能携带数据,但要消耗一个序号。这时TCP 客户端进程进入 SYN-SENT(同步以发送)状态
  • 3、B 收到连接请求报文段后,如同意建立连接,则向 A 发送确认。在确认报文段中应把 SYN 位和 ACK 位都置为 1 ,确认号是 ack = x+1,同时也为自己选择一个初始序号 seq = y。这个报文段也不能携带数据,但要同时消耗一个序号。这时 服务器进程进入 SYN-RCVD(同步收到)状态
  • 4、TCP客户端收到B确认之后,还要向B发送确认。确认报文段 ACK 置为 1 ,确认号 ack = y + 1,而自己的序号 seq = x+1。TCP规定,ACK 报文段可以携带数据。但是如果不携带数据则不消耗序号。在这种情况下,下一个数据报文段的序号仍然是seq = x + 1.这时 TCP进入ESTABLISHED(已连接状态)。当B收到A的确认后,也进入ESTABLISHED状态
    至此三次握手完毕!

面试常问:为什么是TCP是三次握手,而不是二次握手?

  • 正常来说,A 发送连接请求,B收到A的连接请求,然后向A发送确认,连接建立,看起来两次握手好像可以欧。
  • 那有没有这样一种情况呢:
    A 发送的第一个请求连接报文段并没有丢失,而是卡在某个网络节点长时间滞留了,导致到连接释放后某个时间才可以到达 B。本来这时一个已经失效的报文段。但 B 收到此失效的连接请求报文段后,就误认为A又一次发送了新的连接请求。于是向A发送确认报文段,同意建立连接。假设没有三次握手,那么只要 B 发送确认了,新的连接就建立了,那 B 就会一直等待 A发来数据,造成B很多资源浪费!
    综上:采用三次握手可以阻止 “已失效的连接请求报文段”
4.2 TCP连接释放

数据传输结束后,通信双方都可以释放连接。现在A和B都处于 ESTABLISHED 状态。
在这里插入图片描述
下面就是四次挥手的过程

  • 1、A的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接。A把连接释放的报文段首部 FIN = 1,其序列号 seq = u,它等于前面已经传送过的数据的最后一个字节的序号加 1 .这时 A 进入 FIN-WAIT-1(终止等待 1 )状态,等待 B 的确认。请注意:TCP 规定,FIN 报文段 即使不携带数据,它也要消耗一个序列
  • 2、B收到 连接释放 报文段后即发送确认,确认号 ack = u+1;而这个报文段是自己的序列号 v ,等于B前面已经传送过的数据的最后一个字节的序号加 1 .然后B进入 CLOSE-WAIT(关闭连接)状态。这时TCP服务器进程通知高层应用进程,因而A 到 B 这个方向的连接就释放了,这时的 TCP 连接处于 半关闭 状态,即 A 已经没有数据要发送了,但B若发送数据,A仍要接受,从B到A这个方向的连接并未关闭,这个状态会持续一段时间。
  • 3、A 收到 B 的确认后,就进入 FIN-WAIT-2(终止等待2)状态,等待 B 发出的连接释放报文段
  • 4、若 B 已经没有要向A发送数据,其应用进程就通知 TCP释放连接,这时 B 发出的连接释放报文段必须 FIN = 1。现假设 B 的序号为 w(在半关闭状态B可能又发送了一些数据)。B 还必须重复上次已经发送的确认号 ack = u+1。这时 B 就进入 LAST-ACK(最后确认)状态,等待B确认
  • 5、A 收到 B 连接释放的报文段后,必须发出确认。在确认报文段中把 ACK 值为1.确认号 ack = w+1,进入到 TIME-WAIT(时间等待状态)。注意: 现在TCP连接还么有释放掉。必须经过时间等待计时器设置的 2MSL 后,A才进入CLOSED状态。时间 MSL叫做最长报文寿命

面试常问:为什么 A 在 TIME-WAIT状态必须等待 2MSL 时间呢?

  • 为了保证 A 发送的最后一个 ACK 报文段能够到达B。这个 ACK 报文段可能会丢失,因此在 LAST-ACK状态的B可能收不到已经发送的 FIN + ACK报文段的确认。B 会超时重传这个FIN+ACK报文段,而A就可以在2MSL时间内收到了B发来的重传,接着A重传一次确认,重新启动2MSL计时器。最后A和B都正常进入 CLOSED状态!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值