TCP的三次握手与四次挥手过程,各个状态名称与含义

三次握手安全

第一次握手:主机A发送位码为syn=1,随机产生seq number=10001的数据包到服务器,主机B由SYN=1知道,A要求创建联机,此时状态为SYN_SENT; 
第二次握手:主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=20001的包,此时状态由LISTEN变为SYN_RECV; 
第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则链接创建成功,双方状态ESTABLISHED。服务器

完成三次握手,主机A与主机B开始传送数据网络

    • 各个状态名称与含义并发

      CLOSED: 这个没什么好说的了,表示初始状态。 
      LISTEN: 这个也是很是容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,能够接受链接了。 
      SYN_RECV: 这个状态表示接受到了SYN报文,在正常状况下,这个状态是服务器端的SOCKET在创建TCP链接时的三次握手会话过程当中的一个中间状态,很短暂,基本 上用netstat你是很难看到这种状态的,除非你特地写了一个客户端测试程序,故意将三次TCP握手过程当中最后一个ACK报文不予发送。所以这种状态 时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。 
      SYN_SENT: 这个状态与SYN_RECV遥想呼应,当客户端SOCKET执行CONNECT链接时,它首先发送SYN报文,所以也随即它会进入到了SYN_SENT状 态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。 
      ESTABLISHED:这个容易理解了,表示链接已经创建了。测试

    • 四次挥手

      img

      FIN_WAIT_1: 这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别 是:FIN_WAIT_1状态其实是当SOCKET在ESTABLISHED状态时,它想主动关闭链接,向对方发送了FIN报文,此时该SOCKET即 进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,固然在实际的正常状况下,不管对方何种状况下,都应该马 上回应ACK报文,因此FIN_WAIT_1状态通常是比较难见到的,而FIN_WAIT_2状态还有时经常能够用netstat看到。 
      FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半链接,也即有一方要求close链接,但另外还告诉对方,我暂时还有点数据须要传送给你,稍后再关闭链接。 
      TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后便可回到CLOSED可用状态了。若是FIN_WAIT_1状态下,收到了对方同时带 FIN标志和ACK标志的报文时,能够直接进入到TIME_WAIT状态,而无须通过FIN_WAIT_2状态。 
      CLOSING: 这种状态比较特殊,实际状况中应该是不多见,属于一种比较罕见的例外状态。正常状况下,当你发送FIN报文后,按理来讲是应该先收到(或同时收到)对方的 ACK报文,再收到对方的FIN报文。可是CLOSING状态表示你发送FIN报文后,并无收到对方的ACK报文,反而却也收到了对方的FIN报文。什 么状况下会出现此种状况呢?其实细想一下,也不可贵出结论:那就是若是双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报 文的状况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET链接。 
      CLOSE_WAIT: 这种状态的含义实际上是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给本身,你系统毫无疑问地会回应一个ACK报文给对 方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正须要考虑的事情是察看你是否还有数据发送给对方,若是没有的话,那么你也就能够 close这个SOCKET,发送FIN报文给对方,也即关闭链接。因此你在CLOSE_WAIT状态下,须要完成的事情是等待你去关闭链接。 
      LAST_ACK: 这个状态仍是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也便可以进入到CLOSED可用状态了。.net

    • 为何创建链接协议是三次握手,而关闭链接倒是四次握手呢? 
      这 是由于服务端的LISTEN状态下的SOCKET当收到SYN报文的建连请求后,它能够把ACK和SYN(ACK起应答做用,而SYN起同步做用)放在一 个报文里来发送。但关闭链接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你全部的数据都所有发送给对方了,因此你能够未 必会立刻会关闭SOCKET,也即你可能还须要发送一些数据给对方以后,再发送FIN报文给对方来表示你赞成如今能够关闭链接了,因此它这里的ACK报文 和FIN报文多数状况下都是分开发送的。资源

    • 为何TIME_WAIT状态还须要等2MSL后才能返回到CLOSED状态? 
      由于虽然双方都赞成关闭链接了,并且握手的4个报文也都发送完毕,按理能够直接回到CLOSED 状态(就比如从SYN_SENT 状态到ESTABLISH 状态那样),可是咱们必须假想网络是不可靠的,你没法保证你(客户端)最后发送的ACK报文必定会被对方收到,就是说对方处于LAST_ACK 状态下的SOCKET可能会由于超时未收到ACK报文,而重发FIN报文,因此这个TIME_WAIT 状态的做用就是用来重发可能丢失的ACK报文。开发

    • 关闭TCP链接必定须要4次挥手吗? 
      不必定,4次挥手关闭TCP链接是最安全的作法。但在有些时候,咱们不喜欢TIME_WAIT 状态(如当MSL数值设置过大致使服务器端有太多TIME_WAIT状态的TCP链接,减小这些条目数能够更快地关闭链接,为新链接释放更多资源),这时咱们能够经过设置SOCKET变量的SO_LINGER标志来避免SOCKET在close()以后进入TIME_WAIT状态,这时将经过发送RST强制终止TCP链接(取代正常的TCP四次握手的终止方式)。但这并非一个很好的主意,TIME_WAIT 对于咱们来讲每每是有利的。get

相关文章
相关标签/搜索