Socket 和 WebSocket 有什么区别?
简化版
名字像,其实完全不是一个层面的东西。Socket 不是协议,而是操作系统提供的一套编程接口(API)——是应用程序调用 TCP/UDP 收发数据的「插座」,位于应用层和传输层之间。WebSocket 是一个真正的应用层协议(有自己的 RFC 规范),规定了握手、数据帧等格式,用来实现浏览器和服务器之间的全双工通信。更准确的区分是:Socket 是「怎么用网络」的编程工具,WebSocket 是「一套通信规则」的协议;WebSocket 的实现底层也要用 Socket 来收发字节。
详细版
| 维度 | Socket | WebSocket |
|---|---|---|
| 本质 | 操作系统的编程接口(API) | 应用层协议(RFC 6455) |
| 层次 | 传输层与应用层之间的抽象 | 应用层 |
| 是不是协议 | 不是,是编程抽象 | 是,有规范 |
| 依赖关系 | 直接操作 TCP/UDP | 建在 TCP 之上,底层用 Socket 实现 |
| 使用者 | 各种语言的网络编程(服务端、客户端) | 主要用于浏览器↔服务器实时通信 |
| 数据形式 | 裸字节流(TCP)/数据报(UDP),没有消息边界 | 有**帧(frame)**结构、有消息边界 |
| 谁定义格式 | 你自己定(应用协议自己设计) | 协议已规定握手 + 帧格式 |
| 浏览器可用 | 不能直接用原始 TCP Socket | 浏览器原生支持 WebSocket |
关键关系:WebSocket 不是 Socket 的一种,而是用 Socket(TCP)实现的一个协议。就像「HTTP 也是用 Socket 实现的」一样——Socket 是底层工具,WebSocket / HTTP 是建在其上的协议。
完整版教学
一、最大的误解:以为它们是同类
因为名字都带 “Socket”,很多人以为 WebSocket 是 Socket 的「网页版」或「升级版」,这是根本性的误解。它们回答的是完全不同的两个问题:
- Socket 回答的是:「我的程序怎么用操作系统的网络能力去收发数据?」——它是手段/工具(API)。
- WebSocket 回答的是:「浏览器和服务器之间按什么规则做全双工通信?」——它是规则/协议。
一个是「工具」,一个是「规则」,压根不在一个维度。要对比,得先把这层看清。
二、Socket 到底是什么:网络编程的「插座」
Socket(套接字)是操作系统提供的一层网络编程抽象。TCP/IP 协议栈在内核里,应用程序不能直接操作;操作系统就封装出一套 Socket API,让你能像操作文件一样操作网络连接:
socket() // 创建一个套接字
bind() // 绑定 IP 和端口
listen() // 监听(服务端)
accept() // 接受连接(服务端)
connect() // 发起连接(客户端)
send() / recv() // 收发数据
close() // 关闭
它的关键特点:
- 它是 API,不是协议——它不规定「数据内容长什么样」,只提供「把字节发出去、把字节收进来」的能力。
- 位于应用层和传输层之间——是应用程序访问 TCP/UDP 的「门」。
- 传的是裸数据:用 TCP Socket 收到的是连续字节流,没有消息边界(这正是「粘包/拆包」问题的根源——你得自己在应用层定义「一条消息到哪结束」)。
所以,HTTP、WebSocket、FTP、你自己发明的协议,本质上都是「用 Socket 收发字节 + 一套自定义的字节格式约定」。Socket 是共同的地基。
三、WebSocket 是什么:一套确定的协议
WebSocket 则是一个写进 RFC 6455 的应用层协议,它明确规定了:
- 握手怎么做:借用 HTTP 发起(
Upgrade: websocket),服务器回 101 Switching Protocols 完成升级。 - 数据怎么组织:以帧(frame) 为单位传输,帧头带 FIN、opcode、掩码、长度等字段,有明确的消息边界(不像裸 TCP 那样要自己切消息)。
- 控制机制:Ping/Pong 心跳、关闭帧等。
它解决的是一个具体业务问题:让浏览器和服务器能全双工、双向实时通信(HTTP 做不到服务器主动推)。而它自己并不直接操作网卡或 TCP——它的实现(无论浏览器内核还是服务端框架)底层仍然是用 Socket 去建立 TCP 连接、收发字节的。
四、二者的真实关系:一个建在另一个之上
把层次画出来就一清二楚:
应用代码
│ 用 new WebSocket(...) ← WebSocket 协议(RFC 6455,帧/握手)
WebSocket 协议实现
│ 用 socket()/send()/recv() ← Socket API(编程接口)
Socket API
│
TCP / IP(内核协议栈)
│
网卡
- WebSocket 依赖 Socket:WebSocket 协议要落地,必须通过 Socket 去建 TCP 连接、发送握手和帧字节。
- Socket 不依赖 WebSocket:Socket 是通用地基,可以用来实现 HTTP、FTP、WebSocket、游戏私有协议……WebSocket 只是众多「建在 Socket 之上的协议」之一。
这层关系可以这样记:WebSocket 是「用 Socket 实现的一种应用层协议」,正如 HTTP 也是用 Socket 实现的协议。
五、为什么浏览器里只有 WebSocket,没有原始 Socket
一个常见困惑:浏览器为什么不让 JS 直接用 TCP Socket,非得给个 WebSocket?
出于安全:如果网页 JS 能随意发起任意 TCP 连接、连任意端口,那浏览器就成了攻击内网、扫描端口的跳板,太危险。所以浏览器不开放原始 Socket,只提供受控的、协议明确的 WebSocket——它握手基于 HTTP(可被服务器校验 Origin 等)、格式规范、安全可控。想在浏览器里做实时双向通信,WebSocket 就是那个「官方许可的口子」。
(在服务端/桌面/移动端等非浏览器环境,语言直接提供 Socket API,你可以用原始 Socket 实现任意协议。)
六、常见误区与追问
| 考点 | 正确口径 |
|---|---|
| Socket | 操作系统提供的网络编程接口抽象 |
| WebSocket | 应用层协议,基于 HTTP Upgrade 建立全双工连接 |
| 层次 | Socket 是 API,WebSocket 是协议 |
TCP socket:
connect/read/write bytes
WebSocket:
HTTP Upgrade -> 101
then WebSocket frames over TCP/TLS
Socket 和 WebSocket 不是竞品:一个是编程接口,一个是浏览器友好的全双工应用层协议。
- 误区:WebSocket 就是 Socket。 WebSocket 是具体协议,Socket 是网络编程 API 抽象。
- 误区:浏览器可以随便创建 TCP Socket。 普通浏览器 JS 不能直接创建任意 TCP socket,WebSocket 是受控的 Web API。
- 误区:WebSocket 不需要 HTTP。 WebSocket 握手借助 HTTP Upgrade,升级后才传 WebSocket 帧。
- 追问:WebSocket 底层一定是 TCP 吗? 经典 WebSocket 运行在 TCP 上,安全版本 wss 运行在 TLS/TCP 上。
- 追问:Socket 编程需要自己处理什么? 连接、粘包拆包、超时、重连、心跳、序列化和协议状态。
- 追问:什么时候用 WebSocket? 浏览器和服务端需要低延迟双向通信,如聊天、协作、行情推送。
七、加强记忆
Socket 是操作系统的网络编程接口(API),不是协议,位于应用层与传输层之间,提供收发字节的能力,传的是没有消息边界的裸字节流——HTTP/WebSocket/FTP 都建在它之上。WebSocket 是应用层协议(RFC 6455),规定了握手(HTTP Upgrade → 101)和帧格式,实现浏览器↔服务器全双工通信。关系:WebSocket 用 Socket 实现,正如 HTTP 也用 Socket 实现。浏览器出于安全只给受控的 WebSocket、不开放原始 Socket。