TCP中三次握手建立和四次握手释放以及相关问题
本文基于个人所学和网上博文所整理,若有不妥处,欢迎留言指出
TCP连接过程中标志位的意义:
| 字符缩写 | 描述 |
| SYN | 同步序号,表示此报文是一个连接请求或连接接受报文 |
| ACK | 确认位,对接收到的报文的确认 |
| FIN | 终止位,表示发送方完成数据发送,用来释放一个连接 |
| RST | 复位连接,表示TCP连接中出现严重错误 |
| PSH | 推送位,尽可能快递将数据送往接受进程 |
一、三次握手建立
1、三次握手建立连接详解
TCP建立连接要进行“三次握手”,即交换三个分组。大致流程如下:
(1)客户端向服务器发送一个SYN J,并进入SYN_SEND状态,等待服务器确认;;
(2)服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1,此时服务器 进入SYN_RECV状态;
(3)客户端再想服务器发一个确认ACK K+1,客户端和服务器进入 ESTABLISHED状态,完成三次握手。。
三次握手发生在socket的那几个函数:

从图中可以看出,当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。
总结:客户的的connect在第三次握手的第二次返回,二服务器的accept在三次握手的第三次返回。
2、若是出现丢包的情况,会如何?(来自:TCP 为什么是三次握手,为什么不是两次或四次?车小胖的回答)(A对应客户端,B对应服务器)
(1)第一个包,即A发给B的SYN 中途被丢,没有到达B
A会周期性超时重传,直到收到B的确认;
(2)第二个包,即B发给A的SYN +ACK 中途被丢,没有到达A
B会周期性超时重传,直到收到A的确认;
(3)第三个包,即A发给B的ACK中途丢失,没有到达B
A发完ACK,单方面认为TCP为Established状态,而B显然认为TCP为Active状态:
- 假定此时双方都没有数据发送,B会周期性超时重传,直到收到A的确认,收到之后B的TCP 连接也为 Established状态,双向可以发包。
- 假定此时A有数据发送,B收到A的 Data + ACK,自然会切换为established 状态,并接受A的 Data。
- 假定B有数据发送,数据发送不了,会一直周期性超时重传SYN + ACK,直到收到A的确认才可以发送数据。
3、TCP 为什么是三次握手,为什么不是两次或四次?
三次握手的目的是什么?以下引用知乎作者郭无心的回答:
在谢希仁著《计算机网络》第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”
另外,三次握手的最主要目的是保证连接是双工的,可靠更多的是通过重传机制来保证的。我们可以通过打招呼的例子来说明。
二、四次挥手释放
1、四次挥手释放过程详解
由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。
(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

这里引用whuslei的博文TCP协议中的三次握手和四次挥手(图解)中更为生动的解释:
假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。Client端收到FIN报文后,"就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。“,Server端收到ACK后,"就知道可以断开连接了"。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!
2、为什么连接的时候是三次握手,关闭的时候却是四次挥手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
3、为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
答:主要是防止最后一个ACK丢失!!!虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。另外在等待2MLS的时间中,五元组(源、目IP和端口号以及协议号)都不能用,是为了防止网络中迟来数据。
Ref:
http://www.cnblogs.com/huhuuu/p/3572485.html
http://blog.csdn.net/whuslei/article/details/6667471
http://www.cr173.com/exam/Cisco_17954_1.html
http://www.8btc.com/baizhantingjiangjun(将军问题)
TCP中三次握手建立和四次握手释放以及相关问题的更多相关文章
- TCP中三次挥手四次握手
1.TCP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上. ...
- socket中TCP的三次握手连接和四次握手释放
三次握手连接 A: 我进来了啊 B:(有人来了安排个位子)回复:好的你进来吧 A:好的: 客户端向服务器发送一个SYN J 服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1 客户 ...
- TCP\IP三次握手连接,四次握手断开分析
TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标 ...
- TCP三次握手连接与四次握手断开
http://blog.csdn.net/whuslei/article/details/6667471(三次握手与四次握手) 1. TCP的三次握手最主要是防止已过期的连接再次传到被连接的主机. 如 ...
- 为什么TCP连接需要三次握手分开需要四次握手?
TCP的三次握手和四次断开TCP是一个面向连接的服务,面向连接的服务是电话系统服务模式的抽象,每一次完整的数据传输都必须经过建立连接,数据传输和终止连接3个过程,TCP建立连接的过程称为三次握手,下面 ...
- TCP/IP 三次握手和四次握手
三次握手建立连接: 第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己 ...
- TCP/IP三次握手四次挥手
本文通过图来梳理TCP-IP协议相关知识.TCP通信过程包括三个步骤:建立TCP连接通道,传输数据,断开TCP连接通道.如图所示,给出了TCP通信过程的示意图. TCP 三次握手四次挥手 主要包括三部 ...
- TCP/IP协议三次握手与四次握手流程解析(转)
一.TCP报文格式 下面是TCP报文格式图: 上图中有几个字段需要重点介绍下: (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标 ...
- TCP的三次握手过程与四次挥手
TCP握手协议 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确 ...
随机推荐
- Qt-QML-安卓编译问题
Qt的强大在于跨平台,但是在某些地方做的还是不好,想我这种白痴,在编译安卓的时候就遇到新的问题,我在PC上面编译没有问题的,跑到安卓上面就会出现问题,我猜测应该是Qt的下面的编译的时候,用的还是旧的安 ...
- 适配chrome65最新selenium-chromedriver
网盘地址:https://pan.baidu.com/s/1BmdwRgD96IL32-3FTFxPSg 密码: 2vg6
- [转]JS私有化的实现——稳妥构造函数
所谓稳妥对象, 指的是没有公共属性, 而且其方法也不引用this的对象.稳妥对象函数遵循与寄生构造函数类似的模式, 但有两点不同: 一是新创建对象的实例方法不引用this: 二是不使用new操作符调用 ...
- 初学DirectX(1)
初学Direct X (1) Direct3D设备用于访问视频卡的帧缓冲区,以及后台缓冲区.由于IDE是vs2013,默认安装了direct 9,只需要在使用头文件(1)并像使用库文件(2)即可 #i ...
- (Python爬虫04)了解通用爬虫和聚焦爬虫,还是理论知识.快速入门可以略过的
如果现在的你返回N年前去重新学习一门技能,你会咋做? 我会这么干: ...哦,原来这个本事学完可以成为恋爱大神啊, 我要掌握精髓需要这么几个要点一二三四..... 具体的学习步骤是这样的一二三.... ...
- TW实习日记:第19天
今天一早上改完信息门户的代码之后,发现接口又出了问题,查了半天都不知道,原来又是网端的问题...真是心累啊,调整了一些细节样式,以及终于把企业微信的消息推送功能做完了.关键就在于有个表存放微信id的字 ...
- vue中如何实现pdf文件预览?
今天产品提出一个优化的需求,就是之前我们做的图片展示就是一个img标签搞定,由于我们做的是海外后台管理系统,那边的人上传的文件时pdf格式,vue本事是不支持这种格式文件展示的,于是就google搜索 ...
- 关于java中“使用了未经检查或不安全的操作、有关详细信息,请使用 ——Xlint:unchecked重新编译”
今天看<算法 第4版>排序章节时,发现了一个了一个小问题.先贴一下代码: public class Selection{ public static void main(String[]a ...
- Python3 下安装python-votesmart
在python2下安装python-smart还比较容易,而python3中由于很多函数库的变化直接使用python setup.py install 命令来安装的话会导致错误,而导致错误的原因就是p ...
- 关于wcf服务编译平台是x86, 运行平台是x64时,如何调试
关于调试CTDC项目中的的 wcf服务时注意事项: 因为wcf项目引用的的 x86的程序集,所以wcf生成的目标平台为x86.故在64系统上调试需要执行下面的脚本 具体操作步骤: 1. 必须使用201 ...