TCP/IP协议详解(二):创建和关闭链接

做者: remcarpediem
联系方式:segmentfaultcsdn简书git

本文转载请注明做者、文章来源,连接,版权归做者全部。github

 看了酷壳网站上的《TCP 的那些事儿》系列文章,有一点很受启发:锻炼一下本身是否使用较少的篇幅将TCP协议讲解清楚。通常的同窗写博文,可能像摊大饼同样,篇幅较多而且罗嗦。我之前写文章时也是这个习惯,因此但愿在之后的博文写做过程当中,尽可能使用比较短的篇幅来说完想要讲的内容。
 为了节约你的时间,本片文章主要讲解一下内容:面试

  • TCP链接的创建和关闭segmentfault

  • TCP报文的ack number和 seq number的含义服务器

TCP状态机

咱们都说TCP是面向链接的传输协议,可是网络传输都是没有链接的,包括TCP也是同样。TCP所谓的“链接”,其实就是通信双方维护的一个“链接状态”,让它看上去像是有链接同样。因此,TCP的状态转移是很是重要的。网络

 TCP的不一样状态和状态转移构成了所谓的TCP状态机,以下图所示。咱们先在介绍一下其中的几个术语和状态
TCP状态机并发

  • 主动打开(active open)是指客户端发送第一个SYN报文,它主动发起创建TCP链接的请求。tcp

  • 被动打开(passive open)是指服务端接受第一个SYN报文而且发回一个SYN报文,它响应创建TCP链接的请求。网站

  • SYN-SENT是指客户端发送第一个SYN报文并等待接受服务端SYN+ACK报文时的状态,一旦接受到SYN+ACK报文,客户端状态就变为创建链接(ESTABLISHED)了。spa

  • SYN-RECEIVED是指服务端接受到第一个SYN报文并发回SYN+ACK报文等待客户端ACK报文时的状态,一旦接受到客户端发送的ACK报文,服务端状态就变成了创建链接。

  • FIN-WAIT-1是指首先但愿关闭TCP链接的一端的状态,当这一段发送FIN报文并等待ACK报文时,它就处于这个状态下。当这一端接受到ACK报文时,它的状态就变成了FIN-WAIT-2。

  • FIN-WAIT-2是指已经关闭本身这端TCP链接的一端等待接受另外一端FIN报文的状态。等到接受到另一端的FIN报文,它的状态就会变成TIME-WAIT。

  • CLOSE-WAIT是指首先收到FIN报文一端的状态,这一端知道另外一端已经要关闭TCP链接了,可是本身这一端还未关闭TCP。

  • LAST-ACK是指首先收到FIN报文一端的状态,这一端也要关闭TCP链接了,而且向另外一端发送了FIN报文。

sequence number和acknowledge number

 sequence number(以后简称为seq)是用来标识从TCP发端到TCP收端发送的数据字节流,它表示在这个报文段中的第一个数据字节的序号。第一条报文的seq为TCP协议本身计算出来的数值ISN,之后的报文的seq为INS加上已经发送数据的长度,好比第一条报文的seq为x,length为100,那么下一条带有数据的报文的seq为x+101。
 而acknowledge number(以后简称为ack)是表示发送确认的一端所指望收到的下一个序号,所以ack是上次成功接收报文的seq数值加一。只有ACK标志为1时,ack才有效。须要注意的是,TCP有些报文是不包含数据字节流信息的,那么它就不会影响到下一个报文的seqence number。在上一端的例子中,一端接受到这个seq为x,长度为100的报文以后,须要发送一个带有ACK标志的报文,其ack值为x+101。

TCP创建链接和关闭链接

 TCP创建链接和关闭链接是TCP协议中比较重要的一部分,也是面试常常会涉及的部分,咱们在这里就来详细讲解一下TCP创建链接和关闭链接过程当中的每一步报文和其目的。
TCP创建和关闭链接

 TCP创建链接和关闭链接的过程也被称为三次握手和四次握手,其中涉及两军通信问题。由于网络通信是不可靠的,因此你没法知道本身发送的报文另一端是否收到,因此必须等待对方发送一个确认接受的报文;对于另一方也是如此,另一方也不清楚本身发送的确认接受报文是否被接受到,因此也但愿对方再发送一个确认报文。可是在不可靠的通讯中,无论几回握手(发送报文)都是有风险的,由于永远没法确认最后一次通讯被送达。通常来讲,握手次数达到3就能够保证通讯信息被正确传达。

 客户端首先发送一个带有SYN标志的报文给服务端,seq为ISN,就是初始化的Sequence Number。如图所示,client发送的SYN报文的seq为x。客户端发送这个报文的目的是通知服务端本身但愿创建一个TCP链接。
 服务端接受到客户端发送的SYN报文,须要返回一个带有SYN和ACK标志的报文,它的seq为服务器端计算得到的ISN,也就是y。它的ack数值是已经收到报文的seq数值+1,也就是x+1。服务器端发送这个报文来通知客户端本身已经收到客户端但愿创建链接的报文,而且赞成创建链接。
 客户端接受到服务端的报文,发送一个带有ACK标志的报文,它的ack数值为y+1。客户端发送这个报文是为了通知服务端本身已经收到了它的报文,能够进行数据传输了。客户端发送完这个报文以后,默认TCP链接已经创建,就能够直接开始发送数据报文了。
 服务端接受到客户端发送的ACK报文以后,就能够直接发送数据啦。

 因为TCP是全双工的协议,也就是说两端能够同时进行数据传输,因此,TCP链接的关闭在两端都关闭以后才正式关闭。当一端已经没有能够传输的数据时,就会发送带有FIN标记的报文,向另外一端表示本身不会在传输数据啦。接受到另外一端的ack报文以后,这一端就不会在发送数据报文(也就是tcp负载)了。可是ack等控制信息报文仍是会发送的。也就是说,两端的FIN报文不必定是连在一块儿的,服务端可能很早就发送FIN报文了,可是客户端能够在服务端发送FIN报文以后继续发送数据报文,而后在发送FIN报文。 如图所示,client先发送带有FIN标志的报文给服务端,表面本身这端已经无数据能够发送了,但愿关闭TCP链接。报文的seq为x+2,ack为y+1。 服务端接受到这个报文以后发送带有ACK标志的报文,其ack为(x+2)+1,也就是x+3。 服务端无数据发送以后,也向客户端发送带有FIN标志的报文,seq为y+1。 客户端接受到该报文以后,发送一个带有ACK标志的报文,其ack为y+2。

相关文章
相关标签/搜索