当前位置: 首页 > news >正文

基于TCP服务的TLV编解码

基于TCP服务的TLV编解码

一、实现思路

  • 实现一个tcp服务端和tcp客户端
  • 通过TLV方式编解码

TLV分别为:标签域(Tag),长度域(Length),内容域(Value)。

二、实现代码

service_test.go

package serverimport ("errors""fmt""github.com/sea-project/sea-pkg/util/conv""io""net""testing"
)const (TypeLen       = 1 // 2^8=256LenLen        = 2 // 2^16=65536ContentMaxLen = 1024 * 64BufLen        = 1 + 2 + 1024*64MsgText = uint8(66) // 文字信息MsgImg  = uint8(88) // 图片信息
)func Test_TLVMain(t *testing.T) {listener, _ := net.Listen("tcp", "127.0.0.1:8888")for {conn, err := listener.Accept()if err != nil {fmt.Println(err)continue}fmt.Println("A client connected :" + conn.RemoteAddr().String())go tcpPipe(conn)}
}func tcpPipe(conn net.Conn) {bufData := make([]byte, BufLen)var err errorvar data []bytefor {_, _ = io.ReadFull(conn, bufData)if len(bufData) == 0 {break}data, bufData, err = Unpack(bufData)if err != nil {conn.Close()}if len(data) == 0 {break}var msgType stringif uint8(data[:1][0]) == 66 {msgType = "文字消息:"} else {msgType = "图片消息:"}fmt.Println(msgType + string(data[1:]))}
}func Unpack(buf []byte) ([]byte, []byte, error) {// 取出消息类型t := uint8(buf[:1][0])if t != 66 && t != 88 {err := errors.New("消息类型错误")return nil, nil, err}// 取出消息长度l := conv.Bytes2uint16(buf[1:3])data := buf[0 : l+3]bufData := buf[l+3:]return data, bufData, nil
}

client_test.go

package clientimport ("bytes""encoding/binary""github.com/sea-project/sea-pkg/util/time""net""testing"
)const (TypeLen       = 1 // 2^8=256LenLen        = 2 // 2^16=65536ContentMaxLen = 1024 * 64BufLen        = 1 + 2 + 1024*64MsgText = uint8(66) // 文字信息MsgImg  = uint8(88) // 图片信息
)func Test_TLVMain2(t *testing.T) {conn, _ := net.Dial("tcp", "127.0.0.1:8888")for i := 0; i < 100; i++ {currTime := time.GetUnixToFormatString(time.CurrentSecond(), "2006-01-02 15:04:05")data := []byte(currTime + " Hello World! \n")data = Pack(data)conn.Write(data)}}func Pack(msg []byte) []byte {var t uint8var l uint16if time.CurrentMilliSecond()%2 == 0 {t = 66} else {t = 88}l = uint16(len(msg))dataBuff := bytes.NewBuffer([]byte{})if err := binary.Write(dataBuff, binary.BigEndian, t); err != nil {return nil}if err := binary.Write(dataBuff, binary.BigEndian, l); err != nil {return nil}if err := binary.Write(dataBuff, binary.BigEndian, msg); err != nil {return nil}return dataBuff.Bytes()
}

http://www.mrgr.cn/news/5674.html

相关文章:

  • OCR文字识别接口如何用Java进行调用
  • Android UI:PopupWindow:API
  • Studying-CodeTop | 3. 无重复字符的最长子串、206. 反转链表、146. LRU 缓存
  • uniapp 地图map画出地市轮廓
  • 2. springboot集成kafka入门使用教程
  • 已解决:java.lang.ClassNotFoundException: com.mongodb.test.test 异常的正确解决方法,亲测有效!!!
  • 进阶岛 - MindSearch(CPU版)部署到github codespace
  • 软件测试-测试分类
  • 独立ip为何高级又安全?
  • Scratch与AI:开启少儿编程的智能之旅
  • 编译原理(极速版)
  • 【简历】25届青岛某一本JAVA简历:中厂不要强调算法,面试官听不懂
  • Nginx(项目管理和LINUX)
  • 新手起步:探索AWS新账户的服务器部署能力与限制
  • CSP-J-链表
  • 创客匠人老蒋在「IP私域发售六脉神剑落地班」现场金句频出
  • C语言与Python的区别
  • OW-VISCap——开放世界视频实例分割方法研究
  • ChatGPT快速完成论文大纲创作【附完整示例】
  • springboot调用sap接口传输数据,RFC协议接口调用,包含linux,windows部署