TCP(控制传输协议)详解

1、传输层概述

  • 在OSI参考模型中,网络层是面向通信的最高层但同时也是面向用户程序的最底层。
  • 传输层的主要作用:
    • 复用:在发送端,多个应用程序公用一个传输层;
    • 分用:在接收端,传输层把从网络层接收到的数据报拆掉IP报头之后依据端口号分派给不同的应用程序
  • 传输层和网络层的主要区别:
    • 网络层为不同主机提供通信服务,而传输层为不同主机的不同应用程序提供通信服务;
    • 网络层指对报文头部进行差错检验,而传输层会对整个报文进行差错检验

2、TCP协议的特点

  • 面向连接的:双方通信之前需要建立连接,通信完成之后还要释放连接
  • 提供可靠的数据交付服务:TCP协议提交的数据保证和发送方发送的数据是完全一致的
  • 提供点到点的通信服务
  • TCP传输是面向字节流,传输过程中数据被划分成一个个的数据报,但这只是为了传输方便
  • TCP是全双工通信,通信双方都能作为发送端发送数据,也能作为接收端接收数据

3、三次握手:当TCP协议中通信双方建立连接的过程称之为三次握手

备注:在TCP协议中,主动发起请求的一方成为客户端,被动接收请求的一方为服务端,但不管是客户端还是服务端,TCP连接建立完成之后都能发送和接收数据。起初,服务器和客户端都为CLOSED状态。在通信开始前,双方都得创建各自的传输控制块(TCB)。服务器创建完TCB后遍进入LISTEN状态,此时准备接收客户端发来的连接请求。

第一次握手:客户端向服务端发送一个建立连接的请求报文,此时的报文头部信息中SYN=1,ACK=0,seq=x,请求报文发送之后客户端便进入了SYN-SENT状态。

  • SYN=1,ACK=0表示该报文段为连接请求报文。
  • x为本次TCP通信的字节流的初始序号。

第二次握手:服务端收到客户端的连接请求的报文后,如果同意连接,则会向客户端发送一个应答报文:SYN=1,ACK=1,seq=y,ack=x+1

服务端在发送完这个报文之后就进入了SYN-RCVD状态。

  • SYN=1,ACK=1表示该报文段为连接同意的应答报文
  • seq=y表示服务端作为发送者时,发送字节流的初始序号。
  • ack=x+1表示服务端希望下一个数据报发送序号从x+1开始的字节。

第三次握手:当客户端收到服务端的连接同意的应答报文后,还要向服务端发送一个确认报文段,表示:服务端发送的连接请求的应答报文已经成功收到。

4、四次挥手:当TCP协议中通信双方释放连接的过程称之为四次挥手

备注:TCP连接是双向的,所以前两次挥手用于断开一个方向的连接,后两次回收用于断开一个方向的连接。

第一次挥手:

  当A认为发送给B的数据已经全部发送完毕,则A主动向B发送释放连接的请求报文,此时,A将进入FIN-WAIT-1状态。

第二次挥手:

  当B接收到A发送的请求断开连接的报文之后,会通知相应的程序从A发送到B的数据已经全部完成,并且从A到B的连接将会断开。此时的B将进入 CLOSE-WAIT状态,并且会向A发送同意断开连接的应答报文。

  A收到该应答之后,进入FIN-WAIT-2状态,等待B发送连接释放请求。

  第二次挥手完成后,A到B方向的连接已经释放,B不会再接收数据,A也不会再发送数据。但B到A方向的连接仍然存在,B可以继续向A发送数据。

第三次挥手:

  当B向A发送完所有的数据之后,B会向A发送连接释放的请求。此时的B便进入LAST-ACK状态。

第四次挥手:

  A收到释放请求后,向B发送确认断开连接的应答报文,此时A进入TIME-WAIT状态。该状态会持续2MSL时间,若该时间段内没有B的重发请求的话,就进入CLOSED状态,撤销TCB。当B收到确认应答后,也便进入CLOSED状态,撤销TCB。

5、为什么连接建立需要三次握手,而不是两次握手?

防止失效的连接请求报文段被服务端接收,从而产生错误。

  若建立连接只需两次握手,客户端其实并没有太大的变化,仍然需要在获得服务端的应答后才进入ESTABLISHED状态,而服务端在收到连接请求后就进入ESTABLISHED状态。如果在客户端发送连接请求的时候网络拥塞,客户端发送的连接请求迟迟到不了服务端,客户端便会超时重发请求,此时如果服务端正确接收连接请求并确认应答,双方便开始通信,通信结束后释放连接。

  此时如果那个失效的连接请求抵达了服务端,由于只有两次握手,服务端收到请求就会进入ESTABLISHED状态,等待接收数据或主动发送数据,但此时的客户端早已进入CLOSED状态,服务端将会一直等待下去,这样浪费服务端连接资源。

6、为什么A要先进入TIME-WAIT状态,等待2MSL时间后才进入CLOSED状态?

  为了保证第四次挥手之后B能够接收到A的确认应答的报文。 因为A发完确认应答报文后直接进入CLOSED状态,那么如果该应答丢失,B等待超时后就会重新发送连接释放请求,但此时A已经关闭了,不会作出任何响应,因此B永远无法正常关闭。

原文地址:https://www.cnblogs.com/BaoZiY/p/10755422.html