TCP是面向连接的协议。传输连接是用来传送TCP报文的。TCP传输连接的建立和释放是每一次面向连接的通信中必不可少的过程。因此,传输连接就有三个阶段,即:连接建立、数据传送和连接释放。输传连接的管理就是使传输连接的建立和释放都能正常地进行。
  在TCP 连接的建立过程主要解决三个问题:
  • 要使每一方都能够知道对方的存在
  • 要允许双方协商一些参数(如窗口最大值、是否使用窗口扩大选项和时间戳等)
  • 能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。

一、TCP连接建立

  TCP建立连接的过程叫做握手,握手需要在客户和服务器之间交换三个TCP报文段。下图画出了三报文握手(three way (three message) handshake,以前译作“三次握手”)建立连接的过程。
 
 

1、连接建立的过程

  1. 一开始A、B 均为关闭状态。B先开启服务器,建立传输控制块TCB。准备接受连接请求,然后处于LISTEN 状态。等待用户连接请求并作出响应。
    • TCB:(Transmission Control Block,存储了每一个连接中的一些重要信息,如:TCP 连接表,指向发送和接受缓存的指针,指向重传队列的指针,当前发送和接受序号等等)
  1. A 也是先创建连接控制模块TCB 。然后A 向B 发送请求报文段,这时首部中的同步位SYN = 1,同时选择一个初始序号 seq = x。TCP 规定,SYN 报文段不能携带数据,但要消耗掉一个序号。然后客户端进入SYN_SENT (同步已发送)状态。
  2. B 接受到A 的连接请求后,如果同意连接需要给A发送确认。确认报文段ACK 置为1,确认号ack = x+1,同时选择一个自己的初始序号seq = y。请注意这个报文段也不能传输数据,但也要消耗一个序号。这是B 进入SYN_RCVD (同步收到)状态。
  3. A 收到B 的确认后,需要再发送一个确认给B。确认报文段ACK 置为1,确认号ack = y + 1,而自己的序号seq = x + 1。TCP 规定,AC 报文段可以添加数据。但如果没有添加数据则不消耗序号。这时,TCP 连接已经建立,A 进入ESTABLISHED (已经建立连接)状态。
  4. B 收到 A 的确认也进入ESTABLISHED (已经建立连接)状态。

2、为什么要进行三次握手

  假设A B 只用两次握手就建立连接。
  当A 第一次发送给B 连接请求时,如果迟迟得不到回应,A会再次发送连接请求。那么现在网络中有两次请求,一般情况下第一次请求挂掉了,那么B 收到第二次请求,然后回应A,连接建立,没毛病。但是第一次请求可能只是滞后了,假设AB断开连接后,B 又收到了第一次请求,又会尝试建立连接,但是A 会觉得自己没有尝试建立连接,从而拒绝B。因为是两次握手,B 会以为自己已经建立连接了,等待A 发送数据,白白浪费资源。
  三次握手就不会出现这个问题,B 在发送确认后,得不到A 的确认,就会知道这是个过时的请求,知道A 没有要求建立连接。

二、TCP连接释放

  数据传输结束后,通信的双方都可以释放连接。下图画出了TCP连接释放“四次挥手”的过程。
 
 

1、连接释放的过程

  首先AB 都处于ESTABLISHED 状态
  1. A 先发送连接释放报文段,并停止发送数据,主动关闭TCP 连接。A 把链接释放报文段首部的中止控制位FIN 置为1 ,其序号为seq = u(等于前一个传输数据的序号+1)。这时A 进入 FIN-WAIT-1(终止等待连接1)状态,等待B 的确认。TCP规定,FIN 报文段即使不携带数据,也会消耗一个序号。
  2. B 收到A 的连接释放报文段后发出确认。确认号ack = u + 1,而报文段自己的序号seq = v(等于前一个传输数据的序号+1)。然后B 进入CLOSED-WAIT(关闭等待)状态,这时A->B方向的连接就已经断开了,TCP 连接处于半关闭状态。
  3. A 收到B 的确认后,进入FIN-WAIT-2(终止等待2)状态,等待B 发送释放报文段。
  4. 若B 发送完数据后,向A 发送TCP 释放报文段。FIN 置为1 ,先假设序号seq = w (B可能又发送了一些数据),B 还必须重复上次已经发送的确认号ack = u + 1。这是B 进入LAST-ACK(最后确认)状态,等待A 的确认。
  5. A 在收到连接释放报文段后发送确认。在确认报文段中把ACK 置为1 ,确认号ack = w + 1,而自己的序号seq = u + 1(TCP 规定,前面发送过的FIN 报文段要消耗一个序号)。然后进入到TIME-WAIT(时间等待)状态。
  6. 现在TCP 连接还没有断掉。必须经过时间等待计时器(TIME-WAIT time)设置的2MSL时间过后,A 才进入到CLOSED 状态。
    • MSL(Maximum Segment Lifetimr)最长报文生存时间,RFC793 建议为2 分钟。
  1. B 收到A 的ACK 后进入CLOSED 状态。

2、为什么A 在TIME-WAIT 必须等待2MSL时间

  1. 为了保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN-ACK报文段。接着A重传一次确认,重新启动2MSL计时器。最后,A和B都正常进入到CLOSED状态。如果A在TIME=WAIT状态不等待一段时间,而是在发送完ACK报文段后立即释放连接,那么就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。这样,B就无法按照正常步骤进入CLOSED状态
  2. 防止已失效的连接请求报文段出现在本链接中。A 在发送完最后一个ACK 后,在经过2MSL 的等待时间可以保证本链接持续时间内发送的报文在网络中消失。这样就不会出现旧连接请求出现在新连接请求里面的情况。  
    • B只要收到了A发出的确认,就进入CLOSED状态。同样,B在撤销相应的传输控制块TCB后,就结束了这次的TCP握手。注意,B结束TCP连接的时间要比A早一些。

3、TCP 保活计时器

  • 除了时间等待器外,TCP 还设有一个保活计时器(keepalive timer)。
  • 当客户与服务器建立了连接,服务器就会发一个探测报文,75秒发一个,若客户端出现故障无法响应服务器端时,连续发10 个探测报文客户端都没响应,则服务器端自动关闭连接。保活计时器默认为2 个小时,每收到一次请求刷新一次。
 
 
 
posted on 2019-06-17 21:33  Jummyer  阅读(518)  评论(0编辑  收藏  举报