第27章 TCP:其他

所属:TCP/IP详解 卷2:实现 来源:TCP/IP详解 卷2:实现

本章描述TCP的其他功能,包括紧急方式回顾、半关闭、复位、各种状态处理和其他TCP特性。


27.1 引言

本章内容

本章讨论TCP的其他功能:

  • 紧急方式回顾
  • 半关闭
  • 复位报文
  • 各种状态的处理
  • 其他TCP特性

本章是TCP部分的补充。


27.2 紧急方式回顾

紧急方式的要点

紧急方式的要点:

  • URG标志 + 紧急指针
  • 通知接收方有紧急数据
  • 紧急数据只有1字节(大多数实现)
  • 数据还是在正常数据流中
  • 只是提前通知

紧急方式是高优先级通知。


紧急方式的实现

发送方实现:

  • 应用发送MSG_OOB数据
  • TCP设置URG标志和紧急指针
  • 立即发送
  • 窗口为0也能发

接收方实现:

  • 收到URG标志
  • 通知应用(SIGURG或select异常)
  • 应用可以用MSG_OOB读取
  • 数据还是按顺序到达

紧急方式的实现比较简单。


紧急方式的问题

紧急方式的问题:

  • 实现不一致
  • 只有1字节
  • 不是真正的带外
  • 容易用错

建议:

  • 少用
  • 只用1字节
  • 注意兼容性

紧急方式要小心使用。


27.3 半关闭

什么是半关闭

半关闭(Half-Close):

  • TCP是全双工的
  • 两个方向独立
  • 可以只关闭一个方向
  • 另一个方向还能传数据

半关闭是单向关闭。


半关闭的场景

半关闭的场景:

  • 客户端发完数据了,发FIN
  • 服务端还有数据要发
  • 服务端可以继续发
  • 发完再发FIN

例子:

  • HTTP/1.0
  • 客户端发请求,然后关闭发送方向
  • 服务端发响应
  • 发完关闭

半关闭用于一端发完了,另一端还没发完。


半关闭的实现

怎么实现半关闭:

  • 应用调用shutdown,SHUT_WR
  • TCP发FIN
  • 进入FIN_WAIT_2状态
  • 还能接收数据

shutdown vs close:

  • shutdown:只关一个方向
  • close:两个方向都关
  • close还有引用计数问题

shutdown实现半关闭。


半关闭的状态

半关闭的状态:

  • 主动关闭方:FIN_WAIT_2
  • 被动关闭方:CLOSE_WAIT

数据传输:

  • 被动关闭方还能发数据
  • 主动关闭方还能收数据
  • 直到被动关闭方也发FIN

半关闭时还能传数据。


27.4 复位报文

复位报文回顾

复位报文(RST):

  • RST标志位为1
  • 用于异常情况
  • 直接复位连接
  • 不用四次挥手

RST用于异常复位。


什么时候发RST

发送RST的情况:

  1. 连接不存在

    • 收到SYN,没有监听
    • 发RST拒绝
  2. 收到不存在的连接的报文

    • 报文不属于任何连接
    • 发RST
  3. 异常关闭

    • 应用异常
    • 发RST而不是FIN
  4. 半开连接

    • 一端关了,另一端不知道
    • 收到报文发RST
  5. 超时

    • 重传太多次
    • 复位连接

各种异常情况发RST。


收到RST的处理

收到RST的处理:

  • 连接复位
  • 释放资源
  • 通知应用
  • 应用收到错误

错误类型:

  • ECONNRESET:连接被复位
  • ECONNREFUSED:连接被拒绝

收到RST连接就断了。


27.5 各种状态的处理

LISTEN状态

LISTEN状态:

  • 服务端监听
  • 等待连接请求

收到SYN:

  • 分配新的PCB
  • 发送SYN+ACK
  • 进入SYN_RCVD状态

收到其他:

  • 发RST
  • 或者丢弃

LISTEN状态处理连接请求。


SYN_SENT状态

SYN_SENT状态:

  • 客户端发了SYN
  • 等SYN+ACK

收到SYN+ACK:

  • 发送ACK
  • 进入ESTABLISHED状态
  • 连接建立

收到SYN:

  • 同时打开
  • 发SYN+ACK
  • 进入SYN_RCVD状态

收到RST:

  • 连接被拒绝
  • 回到CLOSED

SYN_SENT状态等待SYN+ACK。


SYN_RCVD状态

SYN_RCVD状态:

  • 收到SYN,发了SYN+ACK
  • 等ACK

收到ACK:

  • 进入ESTABLISHED状态
  • 连接建立

收到RST:

  • 回到LISTEN
  • 或者CLOSED

收到FIN:

  • 发RST?
  • 或者正常处理?

SYN_RCVD状态等待ACK。


ESTABLISHED状态

ESTABLISHED状态:

  • 连接建立
  • 可以传数据

收到数据:

  • 按序号处理
  • 放入接收缓冲区
  • 发送ACK

收到ACK:

  • 确认发送的数据
  • 更新窗口
  • 可能触发发送

收到FIN:

  • 进入CLOSE_WAIT状态
  • 发ACK
  • 通知应用

ESTABLISHED是正常传输状态。


TIME_WAIT状态

TIME_WAIT状态:

  • 主动关闭的最后状态
  • 等待2MSL

收到FIN:

  • 重发ACK
  • 重置定时器

收到其他:

  • 一般忽略
  • 或者发RST?

超时:

  • 进入CLOSED
  • 释放资源

TIME_WAIT等待2MSL。


27.6 其他TCP特性

IP选项和TCP

IP选项对TCP的影响:

  • 源站选路
  • 记录路径
  • 时间戳
  • 安全选项

TCP怎么处理:

  • TCP不管IP选项
  • IP层处理
  • TCP只关心数据

IP选项由IP层处理。


多播和TCP

多播和TCP:

  • TCP不支持多播
  • TCP是点对点的
  • 多播是一对多
  • UDP支持多播

为什么TCP不支持多播:

  • TCP是可靠的
  • 多播可靠很难
  • 状态太多
  • 实现复杂

TCP不支持多播。


广播和TCP

广播和TCP:

  • TCP不支持广播
  • TCP是点对点的
  • 广播是一对所有
  • UDP支持广播

为什么TCP不支持广播:

  • 广播不可靠
  • TCP需要确认
  • 广播确认太多
  • 不现实

TCP不支持广播。


TCP和UDP的比较

TCP vs UDP:

对比项TCPUDP
连接面向连接无连接
可靠性可靠不可靠
顺序保证顺序不保证
流量控制有无
拥塞控制有无
开销大小
速度慢快
适用场景文件传输、网页视频、语音、DNS

TCP和UDP各有优缺点。


27.7 小结

紧急方式回顾

  1. 要点

    • URG标志 + 紧急指针
    • 1字节紧急数据
    • 提前通知
  2. 问题

    • 实现不一致
    • 少用,小心用

半关闭

  1. 什么是半关闭

    • 单向关闭
    • 另一个方向还能传
  2. 场景

    • 一端发完了
    • 另一端还没发完
  3. 实现

    • shutdown(SHUT_WR)
    • FIN_WAIT_2 / CLOSE_WAIT

复位报文

  1. 什么时候发

    • 连接不存在
    • 异常关闭
    • 半开连接
    • 超时
  2. 收到RST

    • 连接复位
    • 通知应用

各种状态处理

  1. LISTEN

    • 处理连接请求
    • 收到SYN发SYN+ACK
  2. SYN_SENT

    • 等SYN+ACK
    • 收到就连接建立
  3. SYN_RCVD

    • 等ACK
    • 收到就连接建立
  4. ESTABLISHED

    • 正常传输
    • 处理数据和ACK
  5. TIME_WAIT

    • 等2MSL
    • 超时关闭

其他特性

  1. IP选项

    • IP层处理
    • TCP不管
  2. 多播/广播

    • TCP不支持
    • UDP支持
  3. TCP vs UDP

    • TCP:可靠、面向连接、开销大
    • UDP:不可靠、无连接、开销小

关键概念

  1. 半关闭

    • 单向关闭
    • shutdown
  2. RST

    • 异常复位
    • 各种异常情况
  3. 状态处理

    • 各种状态的处理
    • 状态机
  4. TCP vs UDP

    • 各有优缺点
    • 按需选择

状态处理