第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的情况:
-
连接不存在
- 收到SYN,没有监听
- 发RST拒绝
-
收到不存在的连接的报文
- 报文不属于任何连接
- 发RST
-
异常关闭
- 应用异常
- 发RST而不是FIN
-
半开连接
- 一端关了,另一端不知道
- 收到报文发RST
-
超时
- 重传太多次
- 复位连接
各种异常情况发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:
| 对比项 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接 | 无连接 |
| 可靠性 | 可靠 | 不可靠 |
| 顺序 | 保证顺序 | 不保证 |
| 流量控制 | 有 | 无 |
| 拥塞控制 | 有 | 无 |
| 开销 | 大 | 小 |
| 速度 | 慢 | 快 |
| 适用场景 | 文件传输、网页 | 视频、语音、DNS |
TCP和UDP各有优缺点。
27.7 小结
紧急方式回顾
-
要点
- URG标志 + 紧急指针
- 1字节紧急数据
- 提前通知
-
问题
- 实现不一致
- 少用,小心用
半关闭
-
什么是半关闭
- 单向关闭
- 另一个方向还能传
-
场景
- 一端发完了
- 另一端还没发完
-
实现
- shutdown(SHUT_WR)
- FIN_WAIT_2 / CLOSE_WAIT
复位报文
-
什么时候发
- 连接不存在
- 异常关闭
- 半开连接
- 超时
-
收到RST
- 连接复位
- 通知应用
各种状态处理
-
LISTEN
- 处理连接请求
- 收到SYN发SYN+ACK
-
SYN_SENT
- 等SYN+ACK
- 收到就连接建立
-
SYN_RCVD
- 等ACK
- 收到就连接建立
-
ESTABLISHED
- 正常传输
- 处理数据和ACK
-
TIME_WAIT
- 等2MSL
- 超时关闭
其他特性
-
IP选项
- IP层处理
- TCP不管
-
多播/广播
- TCP不支持
- UDP支持
-
TCP vs UDP
- TCP:可靠、面向连接、开销大
- UDP:不可靠、无连接、开销小
关键概念
-
半关闭
- 单向关闭
- shutdown
-
RST
- 异常复位
- 各种异常情况
-
状态处理
- 各种状态的处理
- 状态机
-
TCP vs UDP
- 各有优缺点
- 按需选择