websocket 对于 raw socket
这里 raw socket 指的就是 直接使用 posix socket api
为什么会有这个对比呢?
因为最近我在做 websocket 测试的时候 ( nodejs, c#, erlang), 发现 websocket 确实方便。
就拿 c# 举例子
-
异步
因为现成的库是基于事件机制的,我只要写callback就行。再也不用管要自己写异步处理,捕获异常,或者多线程。 -
其他好处
网上说的很多,因为websocket握手是一个 http 请求过程,所以http的基础设施都能拿来用。 session, auth, proxy, load blance... -
服务端的实现也很容易。
总之就是要提高生产力
但是 担心 websocket 发送的数据包 体积过大,造成不必要的网络浪费,于是估算了一下 websocket 一个 frame 比 一个 raw tcp 包到底多 多少 字节。
websocket 包格式
websocket 有自己定义的 frame 格式 https://tools.ietf.org/html/rfc6455
frame.jpg每一个 frame 包含 头部 2Bytes 的固定长度,后面根据发送的数据长度可能会包含 0/2/8 Bytes 的长度
如果是客户端发给服务器的,那么还要包含 4Bytes 的Masking-key长度。
raw socket 包格式
+---------+--------------+
| Header | Body |
+---------+--------------+
Header 表示 Body 长度, 一般 都是 2 Bytes, 或者 4 Bytes .
下面用 4 Bytes 做对比。
包体额外长度对比
根据要发送数据的长度,将对比分为以下情况:
- A: 数据长度<= 125
- B: 数据长度<= 2^16
- C: 数据长度 <= 2^32
- D: 数据长度 <= 2^64
A: 数据长度<= 125
- 客户端
- websocket: 2 + 4
- raw socket: 4
- 服务端
- websocket: 2
- raw socket: 4
B: 数据长度<= 2^16
- 客户端
- websocket: 2 + 2 + 4
- raw socket: 4
- 服务端
- websocket: 2 + 2
- raw socket: 4
C: 数据长度 <= 2^32
- 客户端
- websocket: 2 + 8 + 4
- raw socket: 4
- 服务端
- websocket: 2 + 8
- raw socket: 4
D: 数据长度 <= 2^64
- 客户端
- websocket: 2 + 8 + 4
- raw socket: 8
- 服务端
- websocket: 2 + 8
- raw socket: 8
websocket比raw socket多出字节数
+---------------------------------------------------+
| 数据长度 | 125 | 2^16 | 2^32 | 2^64 |
+------------+---------+---------+--------+---------+
| 客户端多出 | 2 | 4 | 10 | 6 |
+------------+---------+---------+--------+---------+
| 服务端多出 | -2 | 0 | 6 | 2 |
+------------+---------+---------+--------+---------+
-
对于实际情况,大部分情况下, 客户端发送的数据长度都在 2^16一下,
此时websocket包比raw socket额外多出2/4个字节 -
同样对于服务器,大部分长度都在 125 到 2^32 之间
此时 websocket包比 raw socket 额外多出 0/6个字节
结论
-
包体长度 websocket 对于 raw socket 还是稍微有点 overhead。
-
服务器接受到的数据得解码一次。也是稍微对CPU有点 overhead
但是在快速容易开发的角度看,还是可以接受的。