漫画:一招学会TCP的三次握手和四次挥手

TCP三次握手和四次挥手的问题在面试中是最为常见的考点之一。不少读者都知道三次和四次,可是若是问深刻一点,他们每每都没法做出准确回答。java

本篇尝试使用动画来对这个知识点进行讲解,指望读者们能够更加简单地地理解TCP交互的本质。面试

image

TCP/IP表明传输控制协议/网际协议,指的是一系列协组。

可分为四个层次设计模式

  • 一、数据链路层、网络层、传输层和应用层。浏览器

  • 二、 在网络层:有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。安全

  • 三、在传输层:中有TCP协议与UDP协议。服务器

  • 四、在应用层:有FTP、HTTP、TELNET、SMTP、DNS等协议。微信

TCP和UDP使用IP协议从一个网络传送数据包到另外一个网络。把IP想像成一种高速公路,它容许其它协议在上面行驶并找到到其它电脑的出口。TCP和UDP是高速公路上的“卡车”,它们携带的货物就是像HTTP,文件传输协议FTP这样的协议等。网络

TCP和UDP是FTP,HTTP和SMTP之类使用的传输层协议。虽然TCP和UDP都是用来传输其余协议的,它们却有一个显著的不一样:TCP提供有保证的数据传输,而UDP不提供。这意味着TCP有一个特殊的机制来确保数据安全的不出错的从一个端点传到另外一个端点,而UDP不提供任何这样的保证。并发

TCP 三次握手

TCP 三次握手就比如两我的在街上隔着50米看见了对方,可是由于雾霾等缘由不能100%确认,因此要经过招手的方式相互肯定对方是否定识本身。框架

image
640

相互拥抱

image

咱们看到这个过程当中一共是四个动做,招手–点头微笑–招手–点头微笑。其中连续进行了2个动做,先是点头微笑(回复对方),而后再次招手(寻求确认),实际上能够将这两个动做合一,招手的同时点头和微笑(syn+ack)。因而四个动做就简化成了三个动做,招手–点头微笑并招手–点头微笑。这就是三次握手的本质,中间的一次动做是两个动做的合并。

咱们看到有两个中间状态,syn_sent和syn_rcvd,这两个状态叫着「半打开」状态,就是向对方招手了,可是还没来得及看到对方的点头微笑。syn_sent是主动打开方的「半打开」状态,syn_rcvd是被动打开方的「半打开」状态。客户端是主动打开方,服务器是被动打开方。

  • syn_sent: syn package has been sent

  • syn_rcvd: syn package has been received

TCP 数据传输

TCP 数据传输就是两我的隔空对话,差了一点距离,因此须要对方反复确认听见了本身的话。

image
6402

客户端喊了一句话(data),接收方听见了以后要回复本身听见了(ack)。

若是喊了一句,半天没听到对方回复,就认为本身的话被大风吹走了,没听见,因此须要从新喊话,这就是tcp重传。

也有多是服务端听到了客户端的话,可是Server向Client的回复被大风吹走了,以致于Client没听见Server的回复。Client并不能判断到底是本身的话被大风吹走了仍是Server的回复被大风吹走了,Client也不用管,重传一下就是。

image
6403

Client能够向Server喊话,一样Server也能够向Client喊话,由于tcp连接是「双工的」,双方均可以主动发起数据传输。不过不管是哪方喊话,都须要收到对方的确认才能认为对方收到了本身的喊话。

Client多是个高射炮,一说连说了八句话,这时候Server能够不用一句一句回复,而是连续听了这八句话以后,一块儿向对方回复说前面你说的八句话我都听见了,这就是批量ack。可是Client也不能一次性说了太多话,Server的脑子短期可能没法消化太多,两人之间须要有协商好的合适的发送和接受速率,这个就是「TCP窗口大小」。

TCP三次链接总结

(1**) 第一次握手:**创建链接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。

**(2) 第二次握手:**服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时本身也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。

**(3) 第三次握手:**客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。

image

完成三次握手,客户端与服务器开始传送数据。

TCP 四次挥手

TCP断开连接的过程和创建连接的过程比较相似,只不过中间的两部并不老是会合成一步走,因此它分红了4个动做,Client挥手(fin)——Server伤感地微笑(ack)——Server挥手(fin)——Client伤感地微笑(ack)。

image

之因此中间的两个动做没有合并,是由于tcp存在「半关闭」状态,也就是单向关闭。Client已经挥了手,但是人尚未走,只是再也不说话,可是耳朵仍是能够继续听,Server呢继续喊话。等待Server累了,也再也不说话了,超Client挥了挥手,Client伤感地微笑了一下,才完全结束了。

image
6405

上面有一个很是特殊的状态time_wait,它是主动关闭的一方在回复完对方的挥手后进入的一个长期状态,这个状态标准的持续时间是4分钟,4分钟后才会进入到closed状态,释放套接字资源。不过在具体实现上这个时间是能够调整的。

它就比如主动分手方要承担的责任,是你提出的要分手,你得付出代价。这个后果就是持续4分钟的time_wait状态,不能释放套接字资源(端口),就比如守寡期,这段时间内套接字资源(端口)不得回收利用。

它的做用是重传最后一个ack报文,确保对方能够收到。由于若是对方没有收到ack的话,会重传fin报文,处于time_wait状态的套接字会当即向对方重发ack报文。

同时在这段时间内,该连接在对话期间于网际路由上产生的残留报文(由于路径过于崎岖,数据报文走的时间太长,重传的报文都收到了,原始报文还在路上)传过来时,都会被当即丢弃掉。4分钟的时间足以使得这些残留报文完全消逝。否则当新的端口被重复利用时,这些残留报文可能会干扰新的连接。

4分钟就是2个MSL,每一个MSL是2分钟。MSL就是maximium segment lifetime——最长报文寿命。这个时间是由官方RFC协议规定的。至于为何是2个MSL而不是1个MSL,我尚未看到一个很是满意的解释。

四次挥手也并不老是四次挥手,中间的两个动做有时候是能够合并一块儿进行的,这个时候就成了三次挥手,主动关闭方就会从fin_wait_1状态直接进入到time_wait状态,跳过了fin_wait_2状态。

TCP四次分手总结

因为TCP链接是全双工的,所以每一个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的链接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP链接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另外一方执行被动关闭。

image

  1. **客户端A发送一个FIN,**用来关闭客户A到服务器B的数据传送(报文段4)。

  2. 服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN同样,一个FIN将占用一个序号。

  3. 服务器B关闭与客户端A的链接,发送一个FIN给客户端A(报文段6)。

  4. 客户端A发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。

总结

TCP状态转换是一个很是复杂的过程,本文仅对一些简单的基础知识点进行了类比讲解。关于TCP的更多知识还须要读者去搜寻相关技术文章进入深刻学习。若是读者对TCP的基础知识掌握得比较牢固,高级的知识理解起来就不会太过于吃力。

补充

最近做为面试管在面试的时候,发现不少人框架很强,java基础的时候就有些薄弱了,不少童鞋们对于HTTP、TCP、UDP以及SOCKET的概念不是很清楚,傻傻的分不清楚,这里咱们也简单的提一下

HTTP自己就是一个协议,是从Web服务器传输超文本到本地浏览器的传送协议。

HTTP(超文本传输协议)是利用TCP在两台电脑(一般是Web服务器和客户端)之间传输信息的协议。客户端使用Web浏览器发起HTTP请求给Web服务器,Web服务器发送被请求的信息给客户端。

HTTP协议是创建在请求/响应模型上的。首先由客户创建一条与服务器的TCP连接,并发送一个请求到服务器,请求中包含请求方法、URL、协议版本以及相关的MIME样式的消息。服务器响应一个状态行,包含消息的协议版本、一个成功和失败码以及相关的MIME式样的消息。

HTTP/1.0为每一次HTTP的请求/响应创建一条新的TCP连接,所以一个包含HTML内容和图片的页面将须要创建屡次的短时间的TCP连接。一次TCP连接的创建将须要3次握手。

另外,为了得到适当的传输速度,则须要TCP花费额外的回路连接时间(RTT)。每一次连接的创建须要这种常常性的开销,而其并不带有实际有用的数据,只是保证连接的可靠性,所以HTTP/1.1提出了可持续连接的实现方法。HTTP/1.1将只创建一次TCP的连接而重复地使用它传输一系列的请求/响应消息,

所以减小了连接创建的次数和常常性的连接开销。

虽然HTTP自己是一个协议,但其最终仍是基于TCP的。

SOCKET:TCP/IP网络的API。

Socket是应用层与TCP/IP协议族通讯的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来讲,一组简单的接口就是所有,让Socket去组织数据,以符合指定的协议。

Socket 接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,用以开发TCP/IP网络上的应用程序。

这是为了实现以上的通讯过程而创建成来的通讯管道,其真实的表明是客户端和服务器端的一个通讯进程,双方进程经过socket进行通讯,而通讯的规则采用指定的协议。socket只是一种链接模式,不是协议,tcp,udp,简单的说(虽然不许确)是两个最基本的协议,不少其它协议都是基于这两个协议如,http就是基于tcp的,用socket能够建立tcp链接,也能够建立udp链接**,这意味着,用socket能够建立任何协议的链接,由于其它协议都是基于此的。

image

**综上所述:**须要IP协议来链接网络;TCP是一种容许咱们安全传输数据的机制,使用TCP协议来传输数据的HTTP是Web服务器和客户端使用的特殊协议。HTTP基于TCP协议,可是却可使用socket去创建一个TCP链接。

更多参考

Android插件包换肤(高仿网易云音乐换肤)

Android中Application是单例,正确吗?

Android App瘦身新姿式——Android App Bundle

关于Java中的不可变性

最后若是对技术比较感兴趣,欢迎关注个人微信公众号:终端研发部,id:codeGooger,一块儿进阶技术

相关文章
相关标签/搜索