TCP系列02—连接管理—1、三次握手与四次挥手
一、TCP连接管理概述
正如我们在之前所说TCP是一个面向连接的通信协议,因此在进行数据传输前一般需要先建立连接(TFO除外),因此我们首先来介绍TCP的连接管理。
通常一次完整的TCP数据传输一般包含三个阶段,分别是连接建立(setup)、数据传输(established)和连接释放(teardown 也称为cleared 或 terminated)。连接管理部分的主要内容则是TCP连接建立与连接释放的方式以及TCP连接状态(connection state)的管理,另外在建立TCP连接的过程中,在发送端和接收端会交换一些选项(option),其中一些选项只能在建立连接的过程中进行交换,有一些则可以在随后的数据传输中进行交换,因此我们也会分别简单介绍一下这些常见的选项。
在TCP的连接建立过程中一般需要处理下面三个问题
- 要使每一方能够确知对方的存在。
- 要允许双方协商一些参数(如最大报文段长度,最大窗口大小,服务质量等)。
- 能够对传输实体资源(如缓存大小等)进行分配
TCP建立连接最常见的方式就是通过三次握手(three-way handshake),连接释放最常见的方式则是四次挥手(four-way handshake或four-way wavehang),下面我们先介绍这两种最常见的连接管理机制。
二、三次握手
三次握手的整个过程如下图所示,一般我们称呼主动发起连接(Active Opener)的一端为客户端(Client),被动等待连接(Passive Opener)的称为服务器端(Server)。此处我们说的客户端和服务器端和我们在WEB开发中使用客户端和服务器端的概念略有差异,WEB开发中一般称呼用户侧为客户端,后台为服务器端,但是后台的服务器端也可以主动向客户端发起TCP连接(尽管这种场景少一些),这个时候后台服务器也就相当于我们下图中的客户端了。
d
下面我们介绍一下整个过程
- A和B的初始状态都是关闭状态,B进入LISTEN状态后被动打开,此时B等待接收客户端的SYN包建立连接。
- A主动打开时,A 的 TCP 向 B 发出连接请求报文段,其首部中的同步位 SYN = 1,选择序号 seq = x,表明传送报文时的第一个字节序号是 x,由于SYN标志在逻辑上占用一个系列号,因此实际数据传输的时候,TCP传输的数据中第一个Byte对应的系列号为x+1。这个SYN包发送以后,A则进入SYN_SENT状态,等待B回复ACK确认包。
- B 的 TCP 收到连接请求报文段后,则发回确认。B 在确认报文段中应使 SYN = 1,使标志位 ACK = 1, 其确认号ack = x + 1,自己选择的序号 seq = y。记得我们之前说过序列号SN实际代表传输了多少比特的数据净荷,实际上在TCP的SYN包中一般并不携带数据,但是由于SYN包和FIN包在协议规定在逻辑上面占1个Byte,因此B在接收到这个SYN包后回复的ack=x + 1。后面我们会讲到消耗系列号SN就意味着这个数据包一旦丢失可以进行重传操作,由于SYN消耗一个byte的系列号,因此SYN数据包丢失的时候是会触发重传的。在B收到A的SYN包并且发送ACK确认包后,B则进入SYN_RCVD状态。
- A 收到此报文段后向 B 给出确认,其 ACK = 1,确认号 ack = y + 1。此时A进入ESTABLISHED状态,A 的 TCP 通知上层应用进程,连接已经建立。
- B 的 TCP 收到主机 A 的确认后,B也进入ESTABLISHED状态,同时通知其上层应用进程当前TCP 连接已经建立。
一般来说上面用来建立连接的初始系列号ISN(即x和y)的值是随机选取的,后面的文章会简单介绍ISN的生成。
三、四次挥手
数据传输结束后,通信的双方都可释放连接。现在如下图假设A 的应用进程先向其 TCP 发出连接释放报文段,并停止发送数据,主动关闭 TCP连接。则四次挥手的过程如下图所示

四次挥手释放连接的流程如下
- 初始状态下A和B都是处于ESTABLISHED状态,当应用层没有待发数据而指示A关闭TCP连接的时候,A 设置连接释放报文段首部的标志位 FIN = 1,ACK=1,其序号seq = u,确认号ack=v,等待 B 的确认。此时A进入FIN_WAIT_1状态
- B 收到A的FIN包的时候,发出确认,由于FIN包与SYN包类似都在逻辑上占1byte,因此确认号 ack = u + 1,而这个报文段自己的序号 seq = v。此时B进入CLOSE_WAIT状态,TCP 服务器进程通知高层应用进程。
- 当A收到B的ACK确认包后,A进入FIN_WAIT_2状态,关于这个状态我们后续在进一步介绍。
- 若 B 已经没有要向 A 发送的数据,其应用进程就通知 TCP 释放连接。B 设置连接释放报文首部的FIN=1,ACK=1,报文序列号seq=v,确认号ack=u+1。此时B进入LAST_ACK状态。
- A 收到连接释放报文段后,必须发出确认,在确认报文段中 ACK = 1,确认号 ack = v + 1,自己的序号 seq = u +1。 此时A进入TIME_WAIT状态。在TIME_WAIT状态下,A经过2MSL时间后就进入关闭状态,关于TIME_WAIT状态我们后续进一步介绍。
- 在B接收到A的确认包后,B立即进入关闭状态。A和B都进入关闭状态后整个TCP连接释放。
四、三次挥手
在四次挥手关闭TCP连接的时候,有时会省略第二条ACK消息,只存在第一条FIN消息、第三条FIN+ACK消息以及第四条FIN消息,从上图四次挥手的过程中可以看到其实第二条消息的ACK Number和第三条消息的ACK Number是相同的,省略第二条的时候其实是第三条消息捎带了第二条消息的ACK,后面完整介绍TCP的状态机的时候,会看到这种省略第二条消息的状态消息。
五、wireshark抓包
对于上面讲到的三次握手和四次挥手,通过wireshark抓包来观察一下

其中进行连接的两个socket(还记得我们前面章节说过一个ip地址+一个端口构成一个socket,或者叫做endpoint吧),一个是127.0.0.1:49324,对应我们前面示意图中的active opener和active closer,另外一个socket是127.0.0.1:9877,则对应passive opener和passive closer。注意wireshark中的系列号Seq呈现的是相对值,所以第一条消息会呈现Seq=0,实际值为0xbc069a3b。wireshark图中[SYN, ACK]表示TCP头中SYN标志位和ACK标志位有效,[SYN]、[FIN, ACK]等含义类似。将wireshark中SYN、FIN两个标志位,以及系列号Seq、应答号Ack与前面的示意图对应起来观察一下吧。
对于三次挥手的情况,wireshark抓包如下为了使两端的seq更容易区分,三次握手后我从client端向server端传输了10bytes数据,如下图高亮的条目所示,传输10bytes后进行三次挥手的TCP连接终止的过程

补充说明
1.TCP连接的建立和终止可以参考RFC793协议
2.第二版<TCP/IP Illustrated Volume1>中给出的四次挥手过程中最后一条消息的seq是错误的
TCP系列02—连接管理—1、三次握手与四次挥手的更多相关文章
- tcp建立连接为什么需要三次握手和四次挥手
前言 众所周知tcp传输层协议在建立连接的时候需要三次才能建立起一个真正的可靠连接,可是为什么是三次呢,不可以是两次,四次等等呢,可以自己思考一番,带着疑问可以看下文. 三次握手 在<计算机网络 ...
- TCP基础知识(二)三次握手与四次挥手
TCP详解(2):三次握手与四次挥手 TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接,就好像你 ...
- 可靠的TCP连接为何是三次握手和四次挥手
首先,咱们先来熟悉下经典的tcp/ip模型. tcp/ip 模型为了方便使用,将osi七层模型划分成了四层,分别为网络接口层,网络层,传输层,应用层. 他们作用分别为: 1)网络接口层:主要作用是将i ...
- TCP:与UDP区别、三次握手、四次挥手、Socket 编程
1. TCP 基本认识 TCP 头部格式 为什么需要 TCP 协议?TCP 工作在哪一层? 什么是 TCP ? 什么是 TCP 连接? 如何唯一确定一个 TCP 连接呢? 有一个 IP 的服务器监听了 ...
- Tcp/Ip--正常情况下的三次握手,四次挥手
三次握手 四次挥手
- TCP的三次握手和四次挥手图解
1. TCP建立连接的三次握手 (1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确 ...
- 面试官求你了,别再问我TCP的三次握手和四次挥手
少点代码,多点头发 本文已经收录至我的GitHub,欢迎大家踊跃star 和 issues. https://github.com/midou-tech/articles 三次握手建立链接,四次挥手断 ...
- TCP系列04—连接管理—3、TCP连接的半打开和半关闭
在前面部分我们我们分别介绍了三次握手.四次挥手.同时打开和同时关闭,TCP连接还有两种场景分别是半打开(Half-Open)连接和半关闭(Half-Close)连接.TCP是一个全双工(Full-Du ...
- TCP连接的建立与释放(三次握手与四次挥手)
TCP连接的建立与释放(三次握手与四次挥手) TCP是面向连接的运输层协议,它提供可靠交付的.全双工的.面向字节流的点对点服务.HTTP协议便是基于TCP协议实现的.(虽然作为应用层协议,HTTP协议 ...
随机推荐
- mysql 多主多从配置,自增id解决方案
MySQL两主(多主)多从架构配置 一.角色划分 1.MySQL数据库规划 我现在的环境是:zhdy04和zhdy05已经做好了主主架构配置,现在需要的是把两台或者多台从服务器与主一一同步. 主机名 ...
- php源码建博客5--建库建表-配置文件-错误日志
主要: 整理框架 建库建表 配置文件类 错误日志记录 --------------本篇后文件结构:-------------------------------------- blog ├─App │ ...
- FMX有一套自己的消息处理机制。类似这样:
unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Var ...
- git 之忽略文件 gitignore 创建和使用规则
1..gitignore文件的创建:首先要强调一点,这个文件的完整文件名就是“.gitignore”,注意最前面有个“.”.这样没有扩展名的文件在Windows下不太好创建,这里给出win7的创建方法 ...
- Python之函数装饰器
在实际中,我们可能需要在不改变函数源代码和调用方式的情况下,为函数添加一些新的附加功能,能够实现这种功能的函数我们将其称之为装饰器.装饰器本质上其实还是是一个函数,用来装饰其它函数,为函数添加一些附加 ...
- Lingo解决最优化问题
目录 Lingo解决优化问题 前言 一.优化模型介绍 二.运输问题 2.1 问题描述 2.2 问题分析 2.2 优化模型构建 2.3 模型求解 2.4 求解结果 三.待更新 Lingo解决优化问题 @ ...
- 用PowerDesign反向生成数据库Sql语句问题
在用Pd15反向生成数据库时,生成的Sql语句在Sql Server Manager Studio里面报错,根本就执行不了.数据库用的是Sql Server 2008 R2.经过一番修 ...
- OSG-简单模型控制
本文转至http://www.cnblogs.com/shapherd/archive/2010/08/10/osg.html 作者写的比较好,再次收藏,希望更多的人可以看到这个文章 互联网是是一个相 ...
- requests,lxml爬启信宝
首先, 添加requests模块: 然后, 添加lxml模块: 启信宝登录抓包: QiXinBao.py: import requestsfrom lxml import etree loginUrl ...
- 破解IDEA注册码,设置 license server一直有效不过期
破解的详细过程: 1.从下面地址下载一个jar包,名称是 JetbrainsCrack-2.10-release-enc.jar 下载地址是http://idea.lanyus.com/,进去之后点 ...