什么是全双工和半双工?

#计算机网络#操作系统#面试八股

什么是全双工和半双工?

按"能不能同时双向传输"划分:单工只能一个方向,半双工能双向但同一时刻只能一个方向,全双工可以同时收发。 电话是全双工,对讲机是半双工,广播是单工。这个区别在链路层表现为"用几对线/几个频段", 在应用层表现为"能不能边收边发"。

1. 三种模式

模式方向同时双向典型例子实现方式
单工 Simplex单向否广播、键盘到主机一对线,固定方向
半双工 Half-duplex双向否对讲机、RS-485、集线器以太网一对线分时复用
全双工 Full-duplex双向是电话、交换式以太网、TCP两对线或频分/回声消除
单工:    A ───────────────► B

半双工:  A ◄──── 分时轮流 ────► B     (发的时候不能收,收的时候不能发)

全双工:  A ──── 发送通道 ────► B
          A ◄─── 接收通道 ──── B       (两条独立通道,可同时进行)

2. 以太网为什么从半双工变成全双工

早期用集线器(hub)时,所有主机共享一条总线:同一时刻只能有一台在发,否则冲突, 靠 CSMA/CD(载波监听多路访问/冲突检测)协调,这就是半双工。

换成交换机(switch)后,每个端口是一条独立的点到点链路,收发各用一对双绞线, 冲突域消失,CSMA/CD 被关闭,于是变成全双工——带宽也从"共享 10Mbps"变成"每端口独享"。

集线器(半双工):          交换机(全双工):
  A ─┐                     A ────┬──── B
  B ─┼─ 共享总线,冲突        C ────┴──── D
  C ─┘                     每个端口独立,无冲突

3. TCP 是全双工的

TCP 连接的两端各有独立的发送序号空间和接收缓冲区,可以同时发数据而互不干扰。 这也是为什么关闭连接需要四次挥手:两个方向要各自发 FIN。

// 全双工:同一个连接上,一边持续读,一边持续写
conn, _ := net.Dial("tcp", "127.0.0.1:9000")

go func() {                       // 写方向
    for i := 0; ; i++ {
        fmt.Fprintf(conn, "ping %d\n", i)
        time.Sleep(time.Second)
    }
}()

buf := make([]byte, 1024)         // 读方向,与写并行
for {
    n, err := conn.Read(buf)
    if err != nil { break }
    fmt.Printf("recv: %s", buf[:n])
}
# 查看网卡协商出来的双工模式与速率
ethtool eth0 | grep -E 'Speed|Duplex'
# 强制全双工(对端必须也一致,否则会大量 CRC 错误)
ethtool -s eth0 speed 1000 duplex full autoneg off

全双工链路如果两端协商不一致(一端全双工、一端半双工),会出现大量冲突与 CRC 错误, 表现为"能通但极慢、丢包"。

4. 常见追问

Q:半双工是不是"轮流发"?靠什么协调? 是分时复用,靠协议协调。以太网用 CSMA/CD(先听后发、边发边听、冲突后退避), RS-485 用主从轮询或令牌,无线 WiFi 用 CSMA/CA(因为无法边发边听)。

Q:为什么无线网络不能算真正的全双工? 同一频段上,设备自身发射的信号会淹没微弱的接收信号(自干扰),所以 WiFi 本质是半双工, 靠时分(TDD)交替收发。要实现全双工需要额外的干扰消除技术。

Q:HTTP 是半双工吗? 语义上是"请求—响应"交替,HTTP/1.1 管线化也只是把请求排队,响应必须按序返回。 HTTP/2 的流(stream)可以在一条连接上多路复用,允许服务端推送,但单个流内部仍是请求响应配对。 真正的双向流要用 WebSocket 或 gRPC streaming。

Q:全双工一定比半双工快吗? 在同样的物理介质上,全双工省掉了冲突与退避,吞吐和时延都更好;但它需要两倍的线路资源 (两对线或两个频段)。光纤用一根纤芯加波分复用也能做到全双工。

小结

单工、半双工、全双工的区别就是"能不能同时双向"。工程上值得记住两点: 以太网从 hub 到 switch 的演进把半双工变成全双工;TCP 因为双向独立序号空间而是全双工, 所以关闭要四次挥手。答题时补一句"全双工需要两条独立通道",就把物理层和应用层连起来了。

笔记加载中…