Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

消息包处理

gtcp提供了许多方便的原生操作连接数据的方法,但是在绝大多数的应用场景中,开发者需要自己设计数据结构,并进行封包/解包处理,由于TCP消息协议是没有消息边界保护的,因此复杂的网络通信环境中很容易出现粘包/断包的情况。因此gtcp也提供了简单的数据协议,方便开发者进行消息包交互,开发者不再需要担心消息包的处理细节,包括封包/解包处理,这一切复杂的逻辑gtcp已经帮你处理好了。

简单协议

gtcp模块提供了简单轻量级数据交互协议,效率非常高,协议格式如下:

...

简单协议由gtcp封装实现,如果开发者客户端和服务端如果都使用gtcp模块来通信则无需关心协议实现,专注数据字段封装/解析实现即可。如果涉及和其他开发语言对接,则需要按照该协议实现对接即可,由于简单协议非常简单轻量级,因此对接成本很低。

数据字段也可以为空,即没有任何长度。

操作方法

https://godoc.org/github.com/gogf/gf/net/gtcp

...

// 数据读取选项
type PkgOption struct {
	HeaderSize  int   // 自定义头大小(默认为2字节,最大不能超过4字节)
	MaxDataSize int   // (byte)数据读取的最大包大小,默认最大不能超过2字节(65535 byte)
	Retry       Retry // 失败重试策略
}

使用示例1,基本使用

package main

import (
	"fmt"
	"github.com/gogf/gf/net/gtcp"
	"github.com/gogf/gf/os/glog"
	"github.com/gogf/gf/util/gconv"
	"time"
)

func main() {
	// Server
	go gtcp.NewServer("127.0.0.1:8999", func(conn *gtcp.Conn) {
		defer conn.Close()
		for {
			data, err := conn.RecvPkg()
			if err != nil {
				fmt.Println(err)
				break
			}
			fmt.Println("receive:", data)
		}
	}).Run()

	time.Sleep(time.Second)

	// Client
	conn, err := gtcp.NewConn("127.0.0.1:8999")
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	for i := 0; i < 10000; i++ {
		if err := conn.SendPkg([]byte(gconv.String(i))); err != nil {
			glog.Error(err)
		}
		time.Sleep(1*time.Second)
	}
}

...

receive: [48]
receive: [49]
receive: [50]
receive: [51]
...

使用示例2,自定义数据结构

大多数场景下,我们需要对发送的消息能自定义数据结构,开发者可以利用数据字段传递任意的消息内容实现。

...