加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Golang加头和尾部来解决tcp粘包问题.代码片段示例

发布时间:2020-12-16 18:33:17 所属栏目:大数据 来源:网络整理
导读:package mainimport ("bufio""encoding/binary""fmt""io""net")var empty []bytefunc main() {lis,_ := net.Listen("tcp",":1789")for {con,err := lis.Accept()if err != nil {continue}//当建立连接的时候交给registerConn来处理这个链接.//想自定义就可以
package main

import (
	"bufio"
	"encoding/binary"
	"fmt"
	"io"
	"net"
)

var empty []byte

func main() {
	lis,_ := net.Listen("tcp",":1789")
	for {
		con,err := lis.Accept()
		if err != nil {
			continue
		}
		//当建立连接的时候交给registerConn来处理这个链接.
		//想自定义就可以把这个函数重写.
		go registerConn(con)
	}
}

type ConnectionInfo struct {
	Conn     net.Conn
	Buf      *bufio.Reader
	Authfunc func(msg []byte) bool
}

type ConnResolve interface {
	OnceRead() ([]byte,error)
	StillRead()
	Close() error
	AuthFuncation(msg []byte) bool
}

func (self *ConnectionInfo) OnceRead() ([]byte,error) {
	return reader(self.Buf)
}

func (self *ConnectionInfo) AuthFuncation(msg []byte) bool {
	return self.Authfunc(msg)
}

func (self *ConnectionInfo) Close() error {
	return self.Conn.Close()
}

func (self *ConnectionInfo) StillRead() {
	for {
		msg,err := reader(self.Buf)
		if err != nil {
			if err == io.EOF {
				continue
			}
			return
		}
		fmt.Printf("收到的信息: %sn",string(msg))
	}
}

func registerConn(conn net.Conn) {
	defer conn.Close()
	//这里返回的是一个接口,可以自定义消息处理机制.
	reg := NewconnectionInfo(conn,nil)
	//接入的时候第一次读取认证信息,然后
	msg,err := reg.OnceRead()
	if err != nil {
		return
	}
	if !reg.AuthFuncation(msg) {
		return
	}
	reg.StillRead()
}

func NewconnectionInfo(conn net.Conn,authfunc func(msg []byte) bool) ConnResolve {
	if authfunc == nil {
		authfunc = DefaultAuthFunc
	}
	return &ConnectionInfo{conn,bufio.NewReader(conn),authfunc}
}

func DefaultAuthFunc(msg []byte) bool {
	fmt.Println("开始校验认证信息: ",string(msg))
	return true
}

//reader方法是用来定义读取的流的逻辑的,可以自己按找自己的逻辑定义.
func reader(buf *bufio.Reader) ([]byte,error) {
	head := make([]byte,5)
	_,err := buf.Read(head)
	if err != nil {
		return empty,err
	}
	bodyLen,_ := binary.Uvarint(head)
	line,err := buf.ReadSlice('n')
	if err != nil {
		return empty,err
	}
	if uint64(len(line)-1) != bodyLen {
		return empty,io.EOF
	}
	return line[:bodyLen],nil
}
func writer(conn net.Conn,msg []byte) (int,error) {
	mgslen := len(msg)
	head := make([]byte,5+mgslen+1)
	binary.PutUvarint(head,uint64(mgslen))
	copy(head[5:],msg)
	head[mgslen] = 'n'
	return conn.Write(head)
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读