golang smux库源码分析

本文介绍了golang的smux库,该库用于socket连接复用。首先展示了客户端和服务端的基本使用代码,接着详细分析了源码,包括如何将conn封装为session,客户端和服务端如何利用session创建stream进行通信,以及如何读取和处理数据帧。
摘要由CSDN通过智能技术生成

1、简介

一个socket连接复用的包https://github.com/xtaci/smux

如图所示,多个channel输入通过smux合并在一个连接中,后端服务将连接中的channel分离出来进行处理。简介就不多写了。

img

1.1 先放客户端和服务端代码, 了解使用方式
package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"github.com/rs/zerolog/log"
	"math/rand"
	"zero/smux"

	"net"
	"time"
)

func init() {
   
	rand.Seed(time.Now().UnixNano())
}

/**
一个生成随机数的tcp服务
客户端发送'R', 'A', 'N', 'D',服务返回一个随机数
*/
func main() {
   
	listener, err := net.Listen("tcp", ":9000")
	if err != nil {
   
		panic(err)
	}
	log.Info().Msg("随机数服务启动,监听9000端口")
	defer listener.Close()
	for {
   
		conn, err := listener.Accept()
		if err != nil {
   
			fmt.Println(err.Error())
			continue
		}
		go SessionHandler(conn)
	}
}

/**
处理会话
每个tcp连接生成一个会话session
*/
func SessionHandler(conn net.Conn) {
   
	session, err := smux.Server(conn, nil)
	if err != nil {
   
		panic(err)
	}
	log.Info().Msgf("收到客户端连接,创建新会话,对端地址:%s", session.RemoteAddr().String())

	for !session.IsClosed() {
   
		stream, err := session.AcceptStream()
		if err != nil {
   
			fmt.Println(err.Error())
			break
		}
		go StreamHandler(stream)
	}
	log.Info().Msgf("客户端连接断开,销毁会话,对端地址:%s", session.RemoteAddr().String())
}

/**
流数据处理
*/
func StreamHandler(stream *smux.Stream) {
   
	buffer := make([]byte, 1024)
	n, err := stream.Read(buffer)
	if err != nil {
   
		log.Error().Msgf("流id:%d,异常信息:%s", stream.ID(), err.Error())
		stream.Close()
		return
	}
	cmd := buffer[:n]
	if bytes.Equal(cmd, []byte{
   'R', 'A', 'N', 'D'}) {
   
		rand := rand.Uint64()
		response := make([]byte, 8)
		binary.BigEndian.PutUint64(response, rand)
		stream.Write(response)
		log.Debug().Msgf("收到客户端数据,流id:%d,随机数:%d, 响应数据:%v", stream.ID(), rand, response)
	} else {
   
		log.Warn().Msgf("收到未知请求命令,流id:%d,请求命令:%v", stream.ID(), cmd)
	}
}
package main

import (
	"encoding/binary"
	"fmt"
	"github.com/rs/zerolog/log"
	"net"
	"net/http"
	"zero/smux"
)

/**
随机数服务客户端连接
*/
var randClient *smux.Session

func init() {
   
	//连接后端随机数服务
	conn, err := net.Dial("tcp", ":9000")
	if err != nil {
   
		log.Warn().
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Golang 抢购茅台源码是指使用 Go 语言编写的程序,用于参与茅台酒抢购的自动化操作。茅台酒作为一种稀缺资源,市场需求大而供应量有限,因此抢购茅台酒成为一件具有挑战的任务。以下是关于 Golang 抢购茅台源码的回答: Golang 抢购茅台源码可以实现自动登录、定时刷新、秒杀等功能,提高购买茅台酒的成功率。在编写这样的源码时,首先需要进行网络请求,向购买茅台的网站发送订单信息。通过解析网页源码,可以获取存数量、距离抢购开始的时间等关键信息。对于每个用户,需要使用不同的账号进行登录,因此需要提供账号管理功能,包括账号的注册、登录、修改密码等。 在抢购过程中,时间非常关键,因此需要设置定时任务。在距离抢购开始前一段时间,程序可以自动获取最新存数量,并将其保存到数据或者内存中。在秒杀开始的瞬间,程序将发送请求到服务器,以尽可能的快速完成购买操作。为了提高抢购的成功率,需要使用高并发的技术,可以使用 Goroutine 实现并发的请求,提高抢购的效率。 不仅如此,还可以通过验证码识别技术,自动识别登录或购买过程中出现的验证码,提高程序的智能化程度。同时,还可以根据历史数据进行分析,预测抢购的最佳时机,以提高抢购成功率。 总体来说,Golang 抢购茅台的源码可以实现自动化的抢购过程,减少人工操作的繁琐,提高购买成功的概率。当然,使用这样的源码需要遵守相关法律法规,确保使用的合法性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值