TCP协议是TCP/IP体系中核心一个协议,该协议比起IP协议,ICMP协议,UDP协议都更复杂,因此这篇文章主要分析TCP协议在建立连接和断开连接的时候,状态转移以及报文段的内容。
下面,先放一张TCP的状态转移图:

TCP协议之三次握手

三次握手的过程是TCP在客户端和服务端建立连接的过程。简单的来说三次握手过程,就是客户端先发送一个连接请求给服务端,这是第一次握手。服务端接收到客户端发来的链接请求,然后在将确认的消息发给客户端,这是第二次握手。客户端对服务端发来的确认消息进行确认,然后将确认的消息发给服务端,这就是三次握手。三次握手之后,链接建立。
为什么一定是三次握手才能建立一个可靠地链接?如果不是三次握手,那么在客户端发送了链接请求之后,服务端对这个请求进行确认,就认定这次的链接已经成功建立,俗称的二次握手。这样的方式的弊端在哪里?
考虑这么一种情况,当客户端进行第一次握手时,发送了一个报文段,但是这个报文段因为网络的问题,迟迟没有到,这时,客户端又会再一次发送一个连接请求的报文段给服务端,这次成功接收,两者建立连接,并通信结束,关闭连接。这之后,因为网络延迟的那个报文段传到了服务端那里,服务端又以为客户端要建立新的连接,于是就同意了,向客户端发送确认。因为是二次握手,所以服务端后续要做的事情,就是等待客户端发送的消息,但是客户端是不会理会服务端传来的确认,所以服务端就会一直在等待客户端的数据,白白浪费了资源。

抓包分析TCP三次握手的报文段

现在,详细说一下三次握手具体是做了什么。
第一次握手,客户端发送一个报文段给服务端,该报文段中标志有SYN标志,该标志表示建立连接,以及一个初始的序列号。
第二次握手时,服务端发送一个报文段给客户端,该报文段中标志有SYN标志,和ACK标志。ACK标志的值是客户端发来的初始序号值+ 1,表示对客户端进行确认,报文段中还有服务端自己的初始序号。
第三次握手时,客户端发送一个报文段给服务端,该报文段中标志只有ACK标志,该ACK值是服务端的初始序列化的值 + 1,表示对服务端进行确认,以及还有一个序号值,该序号值为客户端第一次握手时的序号值 + 1。
三次握手建立连接结束。

图片上共有三行,每一行代表一次握手。我们先看第一行

可以看出,第一次握手时55732端口的程序主动发送一个建立链接的报文段给8888端口。这个55732端口是Java程序写的一个Socket客户端,8888端口是Socket程序写的服务端。建立连接的报文段,Flags中,只有SYN是为1的,这表明这是一个建立连接的报文段,该报文段中初始的序列号为0,ACK的number也为0。

第二次握手,是服务端发送给客户端一个报文段,表示确认收到了客户端的链接请求。该报文段中标志位有两个一个是ACK,一个SYN。表示收到链接请求,端口开放。该报文段中也会发送一个服务端自己的初始序列号。注意,这里ACK的值变成了1,是客户端初始序列号 + 1才有的。

第三次握手,是客户端发送给服务端一个报文段,表示确认收到了服务端的确认。因为双方端口都已经打开,所以客户端在发,就不会再有SYN标志了,这里只有ACK标志,该标志的值也是1,是因为服务端的初始序列号 + 1造成的。这里的序列号为1,是因为第一次握手,发送了一个SYN标志,该标志会占用1个序号值,但是ACK不会。
对应到上面的状态图中,就是客户端是主动打开,从起始点发送SYN报文段,进入SYN_SENT状态,然后接受SYN,ACK,走黑粗线的路径进入到数据传输状态,也就是ESTABLISHED,对于服务端而言,就是从起始点走虚线的部分,被动打开后,接受客户端的SYN,进入SYN_RCVD,最后,接受客户端第三次握手的ACK,进入数据传输状态,也就是ESTABLISHED。

TCP协议之四次挥手

TCP协议是一种全双工协议,拥有半关闭的特性。

全双工的意思是A可以往B发送数据,B同时也可以给A发送数据。
半双工的意思是A可以往B发送数据,B也可以给A发送数据,但是两者不能同时。
单工的意思是只能A给B发送数据,或者B给A发送数据。
半关闭的意思是将全双工,变成单工,也就是如果B关闭,是指B不能给A发数据了,但是A可以给B发

所以TCP协议如果要正常的关闭客户端与服务端的链接,需要四次报文段,也就是4次挥手。
首先,客户端因为应用程序的执行完毕,会主动开始断开链接,这时会发送一个含有FIN标志位的报文段。这表明客户端不会再发送数据给服务端。这时第一次挥手。
然后,服务端接收到这个报文段,就会发送一个含有ACK标志的报文段给客户端,表示确认收到了关闭的报文段。这是第二次挥手。
然后,服务端在处理完服务端的事情后,也会发送一个含有FIN的报文段给客户端,表示服务端不会再发送数据给客户端。这是第三次挥手。
最后,客户端收到这个报文段后,就会发送一个含有ACK的报文段给服务端,表示确认收到了关闭的报文段。这是第四次挥手。至此,链接全部关闭。

抓包分析TCP四次挥手的报文段


不用看黑色报文,4行代表关闭的4次挥手的过程,每一行是一次挥手。
第一行,是客户端主动关闭链接,发送一个含有FIN的报文段,这是第一次挥手
第二行,是服务端确认客户端的FIN报文,发送一个ACK的确认报文,该ACK的值是9,而第一行的序列号的8,因为与SYN一样,FIN也占一个序列号。
忽略黑的后第三行,服务端发送一个含有FIN的报文段,这是第三次挥手。
第四行,客户端会这个FIN报文段进行确认,发送了一个ACK报文段。该ACK的值是第三行的序列号 + 1。

对应到上面的状态图中,先说服务端的状态转移,因为收到了客户端的FIN,所以发送一个ACK给客户端,同时自己进入到CLOSE_WAIT状态,等待服务端应用程序结束,发送FIN给客户端,自己进入LAST_ACK状态,等待最后的ACK到来,接收到ACK,结束状态。

客户端因为先发起关闭,状态比较复杂,他先发送一个FIN给服务端,自己进入了FIN_WAIT_1状态,这时他等待接收服务端的报文,该报文会有三种可能:

  1. 只有服务端的ACK
  2. 只有服务端的FIN
  3. 基于服务端的ACK,又有FIN

对于第一种,该ACK是服务端确认了客户端的FIN而发的,这时客户端会进入FIN_WAIT_2状态,这是当他收到服务端的FIN来时,发送了一个ACK,会进入到TIME_WAIT状态,他要在这个状态等待2MSL的时间,1个MSL是报文段在网络的最长时间,客户端等待2MSL,是为了当最后一个ACK丢失时,可以在发送一次,因为这时,服务端在等待超时后在发送一个FIN给客户端,所以客户端也知道了ACK丢失了。

对于第二种,只有服务端的FIN的时,会发送一个ACK给服务端,客户端进入CLOSING状态,然后接收到服务端的ACK时,也会进入TIME_WAIT状态。

对于第三种,同时都收到了,就省略了进入CLOSING状态,直接进入TIME_WAIT状态。抓包分析的截图,就是这种情况。

TCP协议之三次握手与四次挥手的更多相关文章

  1. TCP协议三次握手与四次挥手通俗解析

    TCP/IP协议三次握手与四次握手流程解析 一.TCP报文格式 TCP/IP协议的详细信息参看<TCP/IP协议详解>三卷本.下面是TCP报文格式图: 图1 TCP报文格式 上图中有几个字 ...

  2. TCP协议三次握手与四次挥手详解

    在计算机网络的学习中TCPi协议与Http协议是我们必须掌握的内容,其中Tcp协议属于传输层,而Http协议属于应用层,本博客主要讲解Tcp协议中的三次握手与四次挥手,关于Http协议感兴趣的可以参看 ...

  3. TCP协议三次握手和四次挥手

    http://www.cnblogs.com/rootq/articles/1377355.html TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对 ...

  4. TCP/IP之三次握手、四次挥手

    参照:http://www.cnblogs.com/hnrainll/archive/2011/10/14/2212415.html 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建 ...

  5. TCP协议三次握手、四次挥手

    TCP的概述 TCP 把连接作为最基本的对象,每一条 TCP 连接都有两个端点,这种断点我们叫作套接字(socket),它的定义为端口号拼接到 IP 地址即构成了套接字,例如,若 IP 地址为 192 ...

  6. TCP协议三次握手、四次挥手过程

    本文通过图来梳理TCP-IP协议相关知识.TCP通信过程包括三个步骤:建立TCP连接通道,传输数据,断开TCP连接通道.如图1所示,给出了TCP通信过程的示意图. 上图主要包括三部分:建立连接.传输数 ...

  7. TCP协议“三次握手”与“四次挥手”详解(下)

    前面进行“三次握手”建立连接后,当客户端的数据发送完毕,它就会要求与服务器端断开连接,那么就要进行“四次挥手”进行连接的释放. 注意,此处所谓的“客户端”与“服务器端”,只是为了方便标识连接的双方,即 ...

  8. TCP协议“三次握手”与“四次挥手”详解(上)

    在使用TCP协议进行数据的传输之前,客户端与服务器端需要建立TCP Connection,即建立连接,之后两端才能进行数据的传输. 下面堆TCP连接“三次握手”的过程进行说明. 1.相关概念 首先,我 ...

  9. TCP/IP协议三次握手和四次挥手大白话解说

    前言 昨天晚上被一位师傅问到了TCP/IP的工作机制,心里很清楚三次握手,然而对于四次挥手却忘了,这是大学习里学过的,奋而翻阅书籍和网络对之前所学的做一个温顾,算是夯实自我吧. TCP(Transmi ...

随机推荐

  1. ROM、RAM、DRAM、SRAM和FLASH的区别

    ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写.ROM在系统停止供电的时候仍然可以保持数据,而RAM通常都是 ...

  2. 新年上班第一天,我的 IDE 挂了

    新的一年又开始了 你年前的总结还记得么?你新年的计划做好了么?反正我都没做. 上班第一天大家都在晒着开工红包,看着一个比一个刷到的红包多,庆幸自己幸好没结婚:开心的聊着过年又被七大姑八大姨爷爷奶奶爸爸 ...

  3. 《JavaScript DOM 编程艺术 》 笔记

    一:这本书由几个案列带入知识点,通俗易懂.最大的收获莫过于作者多次提到的逐渐增强和平稳退化. "渐进增强"指的是给所用用户同等的基本使用体验,再根据用户终端的级别给予更高级的用户更 ...

  4. c#.net的网站出现“正在中止线程””异常的原因和解决方法

    出现“正在中止线程”异常通常都是由于以下三种原因导致引起,给出解决方案如下: 解决方案: 1.针对Response.End,调用 HttpContext.Current.ApplicationInst ...

  5. 解决npm install安装了太多架包的问题

    比如我安装gulp时,会多出很多无用的包,如下图: 经过查询,原来是npm升级了导致的,在npm3.0以上的版本,包的依赖不再安装在每个架包的node_modules文件夹内,而是安装在顶层的node ...

  6. Raspberry树莓派学习笔记2—配置RobotFramework自动化测试环境

    一般RobotFramework都是安装在Windows/Linux的PC机上,这里将简单介绍在树莓派硬件平台上配置RobotFramework的开发和运行环境. 树莓派上配置了自动化测试软件,可以考 ...

  7. unity脚本的运行顺序以及单例的实现

    unity引擎把所有脚本先行编译后,在运行的时候一批,一批的函数进行执行. unity脚本自带函数执行顺序如下:将下面脚本挂在任意物体运行即可得到 Awake ->OnEable-> St ...

  8. vmware安装黑苹果教程

    1.下载最新版vmware http://pan.baidu.com/s/1pLD8wxt 秘钥:UY192-0DW12-M81XY-DWW7C-MCKU6 2.确保hyper-v功能已关闭 3.下载 ...

  9. CSS3 3D的总结(初学者易懂)

    CSS3 3D案例的总结 如果要说是3D的基础概念,首先我就来说一说rotateX().rotateY().rotateZ()这几个属性 rotateX():对应的是3D模型中的X轴上的旋转,传入的参 ...

  10. Kettle 4.4.2源码分析

    一.获取并编译源码 1.1.获取源码 SVN:svn://source.pentaho.org/svnkettleroot/archive/Kettle/branches GitHub:https:/ ...