一、本质区别

Socket 是操作系统提供的网络通信 API(传输层接口);WebSocket 是基于 TCP 的应用层协议。WebSocket 底层用的就是 Socket,但附加了完整的协议规范。

二、Socket(套接字)

2.1 是什么

Socket 是操作系统内核提供的网络编程接口,位于传输层(TCP/UDP)与应用层之间。它本身不是协议,而是一组系统调用(connect、send、recv、bind、listen 等)。

┌─────────────┐
│   应用层     │  ← HTTP、FTP、SMTP、WebSocket
├─────────────┤
│   传输层     │  ← TCP、UDP
├─────────────┤
│  Socket API │  ← 操作系统提供的编程接口
├─────────────┤
│   网络层     │  ← IP
├─────────────┤
│   链路层     │  ← Ethernet、WiFi
└─────────────┘

2.2 Java 中的 TCP Socket 示例

// 服务端
ServerSocket serverSocket = new ServerSocket(8080);
Socket clientSocket = serverSocket.accept();

// 读取数据(裸字节流)
InputStream in = clientSocket.getInputStream();
byte[] buffer = new byte[1024];
int len = in.read(buffer);  // 读到的只是字节数组,没有消息边界

// 发送数据
OutputStream out = clientSocket.getOutputStream();
out.write("hello".getBytes());

Socket 的特点

  • 传输的是裸字节流,没有消息边界概念
  • 需要自己处理粘包/拆包(如定义消息头长度、固定分隔符)
  • 需要自己实现心跳、重连、加密、压缩
  • 浏览器无法直接使用原生 TCP Socket(安全沙箱限制)

三、WebSocket

3.1 是什么

WebSocket 是 HTML5 引入的应用层协议(RFC 6455),设计目标是让浏览器与服务器建立全双工、持久化的通信通道。
建立过程

客户端                              服务端
  │ ─────── HTTP 请求 ────────▶   │
  │  GET /chat HTTP/1.1          │
  │  Host: server.example.com    │
  │  Upgrade: websocket          │
  │  Connection: Upgrade         │
  │  Sec-WebSocket-Key: dGhl...  │
  │                              │
  │ ◀────── HTTP 响应 ─────────   │
  │  HTTP/1.1 101 Switching      │
  │  Upgrade: websocket          │
  │  Sec-WebSocket-Accept: s3p...│
  │                              │
  │ ═══════ WebSocket 连接建立 ═══│  ← 之后不再是 HTTP,而是 WebSocket 帧
  │  0x81 0x05 0x48 0x65...     │
  │  (帧头 + 掩码 + 载荷数据)      │

3.2 Java 中的 WebSocket 示例

// 客户端(浏览器 JS)
const ws = new WebSocket('ws://localhost:8080/chat');

ws.onopen = () => {
    ws.send('Hello Server');  // 发送的是完整消息,不是字节流
};

ws.onmessage = (event) => {
    console.log('收到:', event.data);  // 收到的是完整消息
};

// 服务端(Java + javax.websocket)
@ServerEndpoint("/chat")
public class ChatServer {
    
    @OnOpen
    public void onOpen(Session session) {
        System.out.println("连接建立: " + session.getId());
    }
    
    @OnMessage
    public void onMessage(String message, Session session) {
        // 收到的已经是完整的消息文本,无需处理粘包
        session.getAsyncRemote().sendText("Echo: " + message);
    }
    
    @OnClose
    public void onClose(Session session) {
        System.out.println("连接关闭");
    }
}

四、核心对比

对比项 Socket(TCP) WebSocket
层次 传输层 API / 操作系统接口 应用层协议(RFC 6455)
协议基础 直接基于 TCP/UDP 基于 TCP,但有自己的握手和帧格式
建立连接 connect() 直接三次握手 先 HTTP 握手,再 Upgrade: websocket
数据格式 裸字节流,无消息边界 帧结构,自带消息边界(文本帧/二进制帧)
浏览器支持 ❌ 不支持(安全限制) ✅ 原生支持
全双工 ✅ 支持 ✅ 支持
消息定向 需要自己实现 内置子协议、扩展协商
心跳机制 完全自己实现 内置 Ping/Pong 帧
安全性 自己实现 TLS/SSL wss:// 天然基于 TLS
代理穿透 复杂 基于 HTTP 握手,易穿透防火墙/代理
适用场景 自定义协议、游戏服务端、物联网、IM 后端 Web 实时推送、在线聊天、股票行情、协同编辑

五、WebSocket 帧结构(与 Socket 的本质差异)

WebSocket 不是简单地在 TCP 上发字符串,而是有严格的帧格式:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
+-------------------------------+-------------------------------+
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |
+---------------------------------------------------------------+

关键字段

  • FIN:是否是最后一帧(支持分片消息)
  • opcode:0x1 文本、0x2 二进制、0x8 关闭、0x9 Ping、0xA Pong
  • MASK:客户端→服务端必须掩码(防止缓存污染攻击)
  • Payload len:载荷长度(7/16/64 位可变长度编码)

而 Socket 发送的数据完全没有这些结构,就是纯字节流。

六、常见误区澄清

误区 1:“WebSocket 是 Socket 的升级版”

错误。WebSocket 不是 Socket 的封装或升级,而是完全不同的概念层次

  • Socket = 操作系统 API
  • WebSocket = 应用层协议

WebSocket 底层确实调用了 Socket API,但上层附加了完整的协议规范(握手、帧、控制帧、关闭流程)。

误区 2:“Socket 通信比 WebSocket 快”

不一定。WebSocket 帧头只有 2~14 字节,开销极小。而 Socket 如果要在应用层实现同等功能(消息边界、心跳、掩码、子协议协商),最终写出来的协议帧可能比 WebSocket 还大。

误区 3:“做即时通讯应该用 Socket 而不是 WebSocket”

看场景:

  • Web 端 IM(浏览器网页聊天)→ 必须用 WebSocket(浏览器不支持原生 TCP Socket)
  • App 后端网关(自定义二进制协议)→ 可以用原生 Socket 或基于 Socket 的自定义协议(如 MQTT)
  • 游戏服务端 → 通常用 Socket + 自定义紧凑协议(如 Protocol Buffers over TCP)

七、选型建议

场景 推荐方案 理由
浏览器实时通信 WebSocket 浏览器原生支持,穿透防火墙容易
Web 推送(股票/聊天/通知) WebSocket / SSE SSE 是单向推送,WebSocket 是双向
移动端 App 长连接 WebSocket / Socket + 自定义协议 WebSocket 库成熟;追求极致性能可用自定义协议
游戏服务端 Socket + 自定义二进制协议 需要最小化包头、最大化吞吐
物联网设备 MQTT over TCP Socket MQTT 是轻量级发布订阅协议,适合低功耗设备
文件传输/大数据流 TCP Socket + 流式协议 WebSocket 有单帧大小限制(虽然可分片)

八、总结

Socket 是"电话线"(物理连接能力),WebSocket 是"微信协议"(建立在电话线上的应用层约定)。做网页实时通信用 WebSocket;做底层高性能网关用 Socket;WebSocket 的底层就是 Socket,但千万别把两者混为一谈。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐