2 分钟
Connect 多路复用
何为 Connect 多路复用
Connect 是什么
Connect 即 连接,在计算机/通讯领域,该词一般是指对两方进行通讯的一个对象。该对象的核心方法有三个:
- Write/Send
- Read/Receive
- Close
通讯双方在建立连接后,双方将分别持有一个 Connect 对象,且双方是对等的,当某一方调用 Write 时,对方就可以从 Read 方法中读取到其 Write 的数据。
因此,通过 Connect 的抽象,就可以实现任意两方进行通讯。
在计算机网络领域 Connect 一般指 TCP Connect 连接。
但是如果将概念扩充到 计算机操作系统(Unix) 领域,一个打开的文件可以是一个连接,又因为 一切皆是文件,因此 一切都是 Connect
多路复用是什么
注意本文讨论的多路复用主要聚焦于 Connect 的多路复用,主要是在逻辑层面的。不讨论 IO 多路复用的相关概念,也不讨论物理层的多路复用(通信学领域)。
Connect 的多路复用。可以用一个例子来解释。
原本 A 和 B 存在多个连接 c1, c2, c3, …, cn, 这些连接本质上都是在连接 c0 上进行通讯的。哪么 c0 就是一条多路复用的连接
连接多路复用的用途
提高网路通讯效率
原本 A、B 之间需要建立多个连接进行通讯,然而一般而言,建立一条连接是需要额外开销的。如果能保持 A、B 之间的通讯协议不变,而只需建立一条连接,则可以减少连接建立的额外损耗。
此场景的例子为 HTTP1.1 到 HTTP2.0 的性能提升
端口转发
原本 客户端 A 需要 访问 服务端 B,但 A 无法直接访问 B 时。
如果提供一个 A 和 B 同时可以访问的服务端 C,此时 B 请求 C 建立一个多路复用连接,这样 客户端 A 访问 C ,通过 C <-> B 间的多路复用连接,即可实现 A -> B 的访问
该场景具体可以应用在:
- NAT 穿透服务
- 不同网段服务的互联
Go 的 相关实现
连接多路复用
https://github.com/hashicorp/yamux
该库可以在 A <-> B 实现一个连接的多路复用。
但是该库比较底层,如果想实现 端口转发 还需要自己实现相关协议。如果是端口转发场景可以直接使用 frp
端口转发
https://github.com/fatedier/frp
该库是一个功能强大,端口转发给 软件包。支持多种协议。其原理图大概如下
------------- client a1
|
| --------- client a2
| |
server (a) ------- ---- proxy server (a) ------- client a...
| |
server (b) ---- frpc1 ----------a---------- ---- proxy server (b) ----- client b
| | |
-------------b--------- frps -
| |
frpc2 ----------c---------- ---- proxy server (c) ----- client c
|
server (c) ------
若 client 可以直接 与 server 通信时,已上图等价于如下效果
---------------------------------------------------------------------- client a1
|
| ------------------------------------------------------------------- client a2
| |
server (a) ---------------------------------------------------------------- client a...
server (b) ---------------------------------------------------------------- client b
--------------------------------------------------------- client c
|
server (c) ------
通过对比,可以看出在 存在 frp 时,client a1, a2, a… 和 server (a) 的通讯的三条连接,是通过 frpc 和 frps 之间 一条连接 a 实现的。
因此 连接 a 就是一条多路复用的连接。