TCP基本认识

88 阅读4分钟

TCP基本认识

TCP定义

  • 面向连接的、可靠的、基于字节流的传输层通信协议

TCP连接定义

  • 用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合有Socket、序列号和窗口大小

TCP、UDP区别

1、连接

  • TCP是面向连接的传输层协议,传输数据前要先建立连接
  • UDP是不需要连接的,即刻传输数据

2、服务对象

  • TCP是一对一的两点服务,即一条连接只有两个端点
  • UDP支持一对一、一对多、多对多通信

3、可靠性

  • TCP是可靠交付数据
  • UDP是尽最大努力传输的,不保证可靠性

4、拥塞控制、流量控制

  • TCP有拥塞控制、流量控制,保证数据传输的安全性
  • UDP没有,网络拥塞也不会影响UDP的发送效率

5、首部开销

  • TCP首部如果没有使用【选项】字段是20字节
  • UDP首部只有8字节

6、传输方式

  • TCP是流式传输,没有边界,但保证顺序和可靠谱
  • UDP是一个包一个包的发送,有边界,但可能会丢包和乱序

7、分片不同

  • TCP的数据如果大于MSS大小,会在传输层分片

  • TCP的数据如果大于MTU大小,会在IP层分片

    • MSS是MTU除去IP首部和TCP首部字节后的大小
    • MTU指最大传输单元,一般IP协议是1500字节

TCP头部

TCP头部图解


  • 序列号:在建⽴连接时由计算机⽣成的随机数作为其初始值,通过 SYN 包传给接收端主机,⽤来解决⽹络包乱序问题。

  • 应答号:指下⼀次「期望」收到的数据的序列号,⽤来解决不丢包的问题。

  • 控制位

    • ACK:该位为 1 时,「确认应答」的字段变为有效
    • SYN: 该位为 1 时,表示希望建⽴连接
    • FIN: 该位为 1 时,表示今后不会再有数据发送,希望断开连接。
    • RST: 该位为 1 时,表示 TCP 连接中出现异常必须强制断开连接

TCP三次握手

  • 开始握手状态

    • 一开始客户端服务端都处于CLOSE状态
    • 服务端进入LISTEN状态
  • 第一次握手

    • 客户端发送SYN报文,请求序列号为客户端随机生成
    • 客户端进入SYN_SEND状态
  • 第二次握手

    • 服务端收到SYN报文,确认应答,应答号为客户端请求序列化+1
    • 服务端发起SYN报文,序列号为服务端随机生成
    • 两次请求可以合成一次
    • 服务端进入SYN_RCVD状态
  • 第三次握手

    • 客户端收到服务端发来的请求,确认应答,应答序列号为服务端序列号+1
    • 客户端处于ESTABLISHED状态,服务端收到请求后同样处于ESTABLISHED状态 TCP三次握手图解

    为什么是三次握手,不是两次或者四次

  • 因为三次握手才能确认双方都有发送和接收能力

  • 防止重复历史连接的初始化

  • 同步序列号

  • 避免资源浪费

  • 两次握手不能做到上述事情

  • 四次握手是冗余的

TCP四次挥手

  • 第一次挥手

    • 客户端发送FIN报文
    • 进入FIN_WAIT1状态
  • 第二次挥手

    • 服务端发送ACK报文
    • 进入CLOSED_WAIT状态
    • 客户端收到ACK报文后进入FIN_WAIT2状态
  • 第三次挥手

    • 服务端发送FIN报文
    • 进入LAST_ACK状态
  • 第四次挥手

    • 客户端发送ACK报文
    • 进入TIME_WAIT状态
    • 如无异常 客户端会在2MSL后进入CLOSE状态
    • 服务端在收到ACK报文后,进入CLOSE状态 TCP四次挥手图解
    • MSL(maximum segment lifetime):最大报文生成时间

为什么需要挥手四次

  • FIN报文可以由任一方发起,客户端发送FIN报文,仅仅表示客户端不再发送数据了但是还能接收数据
  • 服务端收到FIN报文后,需要先发送ACK报文确认收到,防止重发,服务端可能还有数据需要处理和发送,等服务端不再发送数据时,再发送FIN报文给客户端

为什么需要TIME_WAIT状态

  • 防止具有相同四元组的旧数据包被收到

    • 四元组是指【源IP 目标IP 源端口 目标端口】
    • 经过2MSL时间,旧的数据包会自然小时
  • 帮助被动关闭端正常关闭连接

    • 如果发送的ACK报文在超过MSL时间内没有被服务端接收,
    • 服务端就会重发FIN报文
    • 这也说明了为什么TIME_WAIT等待的时间2MSL,即客户端的ACK报文和服务端重发FIN报文最久是2MSL

为什么TIME_WAIT等待的时间是2MSL

  • 如果发送的ACK报文在超过MSL时间内没有被服务端接收,
  • 服务端就会重发FIN报文
  • 这也说明了为什么TIME_WAIT等待的时间2MSL,即客户端的ACK报文和服务端重发FIN报文最久是2MSL