首页 > 其他 > 详细

Go 粘包

时间:2020-07-05 12:59:38      阅读:60      评论:0      收藏:0      [点我收藏+]

解决粘包:

用前4个字节存数据的长度, 剩下的字节存数据

(  大端和小端:数据存取和读取的顺序

16进制数:0x123456 占用3个字节

协议用4字节存数据长度

12 34 56 00 大端,高位在左边

00 56 34 12 小端 ,高位在右边)

 

// socket_stick/proto/proto.go
package proto

import (
  "bufio"
  "bytes"
  "encoding/binary"
)

// Encode 将消息编码
func Encode(message string) ([]byte, error) {
  // 读取消息的长度,转换成int32类型(占4个字节)
  var length = int32(len(message))    // 计算msg长度,放入4字节int中
  var pkg = new(bytes.Buffer)
  err := binary.Write(pkg, binary.LittleEndian, length)   //  写入msg长度。小端的方式存放
  if err != nil {
    return nil, err
  }
  err = binary.Write(pkg, binary.LittleEndian, []byte(message))   // 写入消息实体。
  if err != nil {
    return nil, err
  }
  return pkg.Bytes(), nil
}

// Decode 解码消息
func Decode(reader *bufio.Reader) (string, error) {
  // 读取消息的长度
  lengthByte, _ := reader.Peek(4)                 // 读取前4个字节的数据(msg的长度)
  lengthBuff := bytes.NewBuffer(lengthByte)
  var length int32
  err := binary.Read(lengthBuff, binary.LittleEndian, &length)
  if err != nil {
    return "", err
  }
  // Buffered返回缓冲中现有的可读取的字节数。
  if int32(reader.Buffered()) < length+4 {
    return "", err
  }

  // 读取真正的消息数据
  pack := make([]byte, int(4+length))
  _, err = reader.Read(pack)
  if err != nil {
    return "", err
  }
  return string(pack[4:]), nil
}

 

Go 粘包

原文:https://www.cnblogs.com/staff/p/13245729.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!