tcp为什么是三次握手
刷知乎看到的,很可爱啊哈哈哈就顺手黏贴过来了
作者:大闲人柴毛毛
链接:https://www.zhihu.com/question/24853633/answer/254224088
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



OK,下面正经地来回答下这个问题,要搞清楚这个问题,首先得了解TCP究竟是如何保证可靠传输的。
TCP三次握手
<img src="https://pic1.zhimg.com/50/v2-576b043d12353928eea6e45373655668_hd.jpg" data-caption="" data-rawwidth="763" data-rawheight="454" class="origin_image zh-lightbox-thumb" width="763" data-original="https://pic1.zhimg.com/v2-576b043d12353928eea6e45373655668_r.jpg">

起初,服务器和客户端都为CLOSED状态。在通信开始前,双方都得创建各自的传输控制块(TCB)。
服务器创建完TCB后遍进入LISTEN状态,此时准备接收客户端发来的连接请求。
第一次握手
客户端向服务端发送连接请求报文段。该报文段的头部中SYN=1,ACK=0,seq=x。请求发送后,客户端便进入SYN-SENT状态。
- PS1:SYN=1,ACK=0表示该报文段为连接请求报文。
- PS2:x为本次TCP通信的字节流的初始序号。
TCP规定:SYN=1的报文段不能有数据部分,但要消耗掉一个序号。
第二次握手
服务端收到连接请求报文段后,如果同意连接,则会发送一个应答:SYN=1,ACK=1,seq=y,ack=x+1。
该应答发送完成后便进入SYN-RCVD状态。
- PS1:SYN=1,ACK=1表示该报文段为连接同意的应答报文。
- PS2:seq=y表示服务端作为发送者时,发送字节流的初始序号。
- PS3:ack=x+1表示服务端希望下一个数据报发送序号从x+1开始的字节。
第三次握手
当客户端收到连接同意的应答后,还要向服务端发送一个确认报文段,表示:服务端发来的连接同意应答已经成功收到。
该报文段的头部为:ACK=1,seq=x+1,ack=y+1。
客户端发完这个报文段后便进入ESTABLISHED状态,服务端收到这个应答后也进入ESTABLISHED状态,此时连接的建立完成!
为什么连接建立需要三次握手,而不是两次握手?
防止失效的连接请求报文段被服务端接收,从而产生错误。
PS:失效的连接请求:若客户端向服务端发送的连接请求丢失,客户端等待应答超时后就会再次发送连接请求,此时,上一个连接请求就是『失效的』。
若建立连接只需两次握手,客户端并没有太大的变化,仍然需要获得服务端的应答后才进入ESTABLISHED状态,而服务端在收到连接请求后就进入ESTABLISHED状态。此时如果网络拥塞,客户端发送的连接请求迟迟到不了服务端,客户端便超时重发请求,如果服务端正确接收并确认应答,双方便开始通信,通信结束后释放连接。此时,如果那个失效的连接请求抵达了服务端,由于只有两次握手,服务端收到请求就会进入ESTABLISHED状态,等待发送数据或主动发送数据。但此时的客户端早已进入CLOSED状态,服务端将会一直等待下去,这样浪费服务端连接资源。
TCP四次挥手
<img src="https://pic2.zhimg.com/50/v2-c8b61ed2a249700583b11bc5d16c5711_hd.jpg" data-caption="" data-rawwidth="772" data-rawheight="524" class="origin_image zh-lightbox-thumb" width="772" data-original="https://pic2.zhimg.com/v2-c8b61ed2a249700583b11bc5d16c5711_r.jpg">

我们知道,TCP连接是双向的,因此在四次挥手中,前两次挥手用于断开一个方向的连接,后两次挥手用于断开另一方向的连接。
第一次挥手
若A认为数据发送完成,则它需要向B发送连接释放请求。该请求只有报文头,头中携带的主要参数为:
FIN=1,seq=u。此时,A将进入FIN-WAIT-1状态。
- PS1:FIN=1表示该报文段是一个连接释放请求。
- PS2:seq=u,u-1是A向B发送的最后一个字节的序号。
第二次挥手
B收到连接释放请求后,会通知相应的应用程序,告诉它A向B这个方向的连接已经释放。此时B进入CLOSE-WAIT状态,并向A发送连接释放的应答,其报文头包含:
ACK=1,seq=v,ack=u+1。
- PS1:ACK=1:除TCP连接请求报文段以外,TCP通信过程中所有数据报的ACK都为1,表示应答。
- PS2:seq=v,v-1是B向A发送的最后一个字节的序号。
- PS3:ack=u+1表示希望收到从第u+1个字节开始的报文段,并且已经成功接收了前u个字节。
A收到该应答,进入FIN-WAIT-2状态,等待B发送连接释放请求。
第二次挥手完成后,A到B方向的连接已经释放,B不会再接收数据,A也不会再发送数据。但B到A方向的连接仍然存在,B可以继续向A发送数据。
第三次挥手
当B向A发完所有数据后,向A发送连接释放请求,请求头:FIN=1,ACK=1,seq=w,ack=u+1。B便进入LAST-ACK状态。
第四次挥手
A收到释放请求后,向B发送确认应答,此时A进入TIME-WAIT状态。该状态会持续2MSL时间,若该时间段内没有B的重发请求的话,就进入CLOSED状态,撤销TCB。当B收到确认应答后,也便进入CLOSED状态,撤销TCB。
为什么A要先进入TIME-WAIT状态,等待2MSL时间后才进入CLOSED状态?
为了保证B能收到A的确认应答。
若A发完确认应答后直接进入CLOSED状态,那么如果该应答丢失,B等待超时后就会重新发送连接释放请求,但此时A已经关闭了,不会作出任何响应,因此B永远无法正常关闭。
tcp为什么是三次握手的更多相关文章
- TCP/IP协议三次握手与四次握手流程解析
原文链接地址:http://www.2cto.com/net/201310/251896.html TCP/IP协议三次握手与四次握手流程解析 TCP/IP协议的详细信息参看<TCP/IP协议详 ...
- 理解TCP为什么需要进行三次握手(白话)
原文地址:http://www.cnblogs.com/yuilin/archive/2012/11/05/2755298.html 首先简单介绍一下TCP三次握手 在TCP/IP协议中,TCP协议提 ...
- TCP/IP协议三次握手与四次握手流程解析(转载及总结)
原文地址:http://www.2cto.com/net/201310/251896.html,转载请注明出处: TCP/IP协议三次握手与四次握手流程解析 一.TCP报文格式 TCP/IP协议的详 ...
- TCP连接建立的三次握手过程可以携带数据吗?
前几天实验室的群里扔出了这样一个问题:TCP连接建立的三次握手过程可以携带数据吗?突然发现自己还真不清楚这个问题,平日里用tcpdump或者Wireshark抓包时,从来没留意过第三次握手的ACK包有 ...
- TCP/IP的三次握手协议
关于TCP/IP的三次握手协议,这篇文章中有详细的介绍,很通俗易懂,什么时候忘了,都可以过来瞧两眼,保证很快就明白了. 首先TCP/IP协议分为三个阶段:建立连接(握手阶段),数据传输阶段,连接终止阶 ...
- 理解TCP为什么需要进行三次握手
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认: ...
- 为什么建立TCP连接需要三次握手,为什么断开TCP连接需要四次握手,TIME_WAIT状态的意义
为什么建立TCP连接需要三次握手? 原因:为了应对网络中存在的延迟的重复数组的问题 例子: 假设client发起连接的连接请求报文段在网络中没有丢失,而是在某个网络节点长时间滞留了,导致延迟到达ser ...
- TCP协议中三次握手
TCP/IP是互联网相关的各类协议族的总称 TCP/IP协议族分为:应用层,传输层,网络层,数据链路层 应用层:向用户提供应用服务时的通讯的活动 传输层:提供处于网络连接中的两台计算机之间的数据传输 ...
- python摸爬滚打之----tcp协议的三次握手四次挥手
TCP协议的三次握手, 四次挥手 三次握手过程 1, 服务器时刻准备接受客户端进程的连接请求, 此时服务器就进入了LISTEN(监听)状态; 2, 客户端进程然后向服务器发出连接请求报文, 之后客户端 ...
- TCP建立连接三次握手和释放连接四次握手
TCP建立连接三次握手和释放连接四次握手 [转载]http://blog.csdn.net/guyuealian/article/details/52535294 在谈及TCP建立连接和释 ...
随机推荐
- 【20190129】CSS-定位问题记录
很多情况下我在写div的时候都不会把高度写死,而是用子元素撑开高度的方式,但是如果子元素设置了浮动或者position绝对定位,就相当于把子元素从文档流中拿出来了,这时父元素的高度就不能被子元素撑开了 ...
- layer.open
1.type-基本层类型 类型:Number,默认:0 layer提供了5种层类型.可传入的值有:0(信息框,默认)1(页面层)2(iframe层)3(加载层)4(tips层). 若你采用layer. ...
- JSP内置对象——pageContext对象和config对象
它对应的常用方法有: 现在,我新建一个“pageContext.jsp”页面,可以获得“session_page1.jsp”这个页面中保存的用户名: pageContext.jap: session_ ...
- 安卓开发_深入理解Activity和Fragment的关系
Fragment(碎片)是必须嵌入在 Activity(活动) 中使用的.Fragment的生命周期随着Activity的生命周期的变化而变化 一.首先让我们看下Activity和Fragment的生 ...
- Kotlin入门(19)Android的基础布局
线性布局线性布局LinearLayout是最常用的布局,顾名思义,它下面的子视图像是用一根线串了起来,所以其内部视图的排列是有顺序的,要么从上到下垂直排列,要么从左到右水平排列.排列顺序只能指定一维方 ...
- 聊聊HTTP gzip压缩与常见的Android网络框架
版权声明: 欢迎转载,但请保留文章原始出处 作者:GavinCT 出处:http://www.cnblogs.com/ct2011/p/5835990.html 进入主题之前,我们先来看一下客户端与服 ...
- (网页)JS中的小技巧,但十分的实用!
转自CSDN: 1.document.write(”"); 输出语句2.JS中的注释为//3.传统的HTML文档顺序是:document->html->(head,body)4. ...
- jQuery搜索框自动补全功能插件实现-autocomplete.js
最近用nodeclub实现股票的输入关键字自动补全股票信息进行搜索功能,原先用jQuery-ui,结果jQuery-ui库太大,所以考虑用其他插件,最终选择使用autocomplete.js,控件简单 ...
- January 03rd, 2018 Week 01st Wednesday
My existence is not without reason. I know that I could be a quite a different person. 我的存在必定有意义,我知道 ...
- Django之ORM查询复习与cookie
ORM查询总结: models.Book.objects.filter(**kwargs): querySet [obj1,obj2] models.Book.objects.filter(**kwa ...