使用cmux实现网络端口复用

本文介绍了Go语言中的cmux库,如何通过查看连接的第一个数据包来识别不同协议,实现在单个TCP监听器上同时服务HTTP、gRPC等协议。给出了一个创建cmux实例并为不同协议设置匹配规则的示例代码。
摘要由CSDN通过智能技术生成

cmux的作用


一般情况下,每个端口只能为一个服务所用,如果复用,会报"port is already in use"

如果需要复用某个端口,那么可以使用cmux来实现(其实大多数情况下必要性不大.比如我就图8888端口吉利,http/grpc等服务都用这个端口)

cmux[1] 全称 Connection Mux, 是Go生态来复用端口的库, 可以在同一个TCP监听器上服务 gRPC、SSH、HTTPS、HTTP、Go RPC等几乎任何其他协议。


实现原理


cmux的实现原理主要是通过"查看"连接的第一个数据包来确定连接的类型。每种类型的连接都有一个匹配器,这个匹配器可以是自定义的,也可以使用cmux库提供的一些内置匹配器。

当一个连接进来时,cmux会将其数据包传递给所有匹配器,看看哪个匹配器会匹配这个数据包。一旦找到一个匹配的匹配器,cmux就会将该连接传递给对应的服务去处理。

cmux 源码分析[2]


示例代码


以下示例创建了一个主监听器,然后为该监听器创建了一个cmux,然后匹配不同的连接并为每种类型的连接创建对应的服务。

package main

import (
 "context"
 "log"
 "net"
 "net/http"

 "google.golang.org/grpc"
 pb "google.golang.org/grpc/examples/helloworld/helloworld"

 "github.com/soheilhy/cmux"
)

func main() {
 lis, err := net.Listen("tcp""localhost:8888")
 if err != nil {
  log.Fatalf("failed to listen: %v", err)
 }

 mux := cmux.New(lis)

 // gRPC 匹配规则
 grpcL := mux.MatchWithWriters(
  cmux.HTTP2MatchHeaderFieldSendSettings("content-type""application/grpc"),
 )
 // otherwise serve http
 httpL := mux.Match(cmux.Any())

 // gRPC server
 grpcS := grpc.NewServer()
 pb.RegisterGreeterServer(grpcS, &server{})

 // HTTP server
 httpS := &http.Server{
  Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   w.Write([]byte("greet from HTTP\n"))
  }),
 }

 // start serving!
 go grpcS.Serve(grpcL)
 go httpS.Serve(httpL)
 log.Printf("serve both grpc and http at %v", lis.Addr())
 if err := mux.Serve(); err != nil {
  log.Fatalf("failed to serve: %v", err)
 }
}

type server struct {
 pb.UnimplementedGreeterServer
}

func (server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
 return &pb.HelloReply{Message: "greet from gRPC"}, nil
}


go mod tidy 而后 go run main.go运行如上代码,

alt

在浏览器地址栏中输入 http://localhost:8888/

alt
alt

如果没有安装greeter_client,可以 go install google.golang.org/grpc/examples/helloworld/greeter_client,

然后再 ${GOPATH}/bin/greeter_client -addr localhost:8888


更多可参考 Go每日一库之139:cmux (连接多路复用)[3]

完整代码: https://github.com/cuishuang/cmux-lab

参考资料
[1]

cmux: https://github.com/soheilhy/cmux

[2]

cmux 源码分析: https://wadevan.github.io/post/cmux/

[3]

Go每日一库之139:cmux (连接多路复用): https://cloud.tencent.com/developer/article/2334531

本文由 mdnice 多平台发布

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值