简介
Smux(Simple MUltipleXing)是Golang的一个复用库。它依赖于底层连接来提供可靠性和排序,如TCP或KCP,并提供面向流的复用。这个库的初衷是为kcp-go的连接管理提供动力。
特点
- 代币桶控制接收,这提供了更平滑的带宽图(见下图)。
- 会话范围内的接收缓冲区,在流之间共享,完全控制整体内存使用。
- 最小化的头(8字节),最大化的有效载荷。
- 在kcptun的数百万设备上进行了良好的测试。
- 内置的公平队列流量整形。
- 每条流的滑动窗口控制拥堵。(协议版本2+)。
基准测试
$ go test -v -run=^$ -bench .
goos: darwin
goarch: amd64
pkg: github.com/xtaci/smux
BenchmarkMSB-4 30000000 51.8 ns/op
BenchmarkAcceptClose-4 50000 36783 ns/op
BenchmarkConnSmux-4 30000 58335 ns/op 2246.88 MB/s 1208 B/op 19 allocs/op
BenchmarkConnTCP-4 50000 25579 ns/op 5124.04 MB/s 0 B/op 0 allocs/op
PASS
ok github.com/xtaci/smux 7.811s
规格
VERSION(1B) | CMD(1B) | LENGTH(2B) | STREAMID(4B) | DATA(LENGTH)
VALUES FOR LATEST VERSION:
VERSION:
1/2
CMD:
cmdSYN(0)
cmdFIN(1)
cmdPSH(2)
cmdNOP(3)
cmdUPD(4) // only supported on version 2
cmdACK(5) // only supported on version 2
CmdMax(6) // only supported on version 2, for custom ID start
STREAMID:
client use odd numbers starts from 1
server use even numbers starts from 0
cmdUPD:
| CONSUMED(4B) | WINDOW(4B) |
使用方法
func client() {
// Get a TCP connection
conn, err := net.Dial(...)
if err != nil {
panic(err)
}
// Setup client side of smux
session, err := smux.Client(conn, nil)
if err != nil {
panic(err)
}
// Open a new stream
stream, err := session.OpenStream()
if err != nil {
panic(err)
}
// Stream implements io.ReadWriteCloser
stream.Write([]byte("ping"))
stream.Close()
session.Close()
}
func server() {
// Accept a TCP connection
conn, err := listener.Accept()
if err != nil {
panic(err)
}
// Setup server side of smux
session, err := smux.Server(conn, nil)
if err != nil {
panic(err)
}
// Accept a stream
stream, err := session.AcceptStream()
if err != nil {
panic(err)
}
// Listen for a message
buf := make([]byte, 4)
stream.Read(buf)
stream.Close()
session.Close()
}