首页 > 其他分享 >gob踩坑记录

gob踩坑记录

时间:2024-04-10 11:29:35浏览次数:18  
标签:记录 myStruct gob io decoder dec 服务端

1.报错gob: duplicate type received

场景: 使用encoder1发送自定义结构体struct1encoder2发送自定义结构体struct2,使用同一个decoder接收这两个结构体。
报错原因: gob在发送自定义结构体时,会先对该类型进行注册。在我们的场景中,encoder1encoder2都向decoder发送注册信息,因此导致类型重复。
解决方法: 对于同一个数据,应使用一一对应的encoderdecoder进行传输。

2.零值被覆盖

场景:

type MyStruct struct {
	id int
	...
}

func handleConn(conn net.Conn) {
	var myStruct MyStruct
	decoder := gob.NewDecoder(conn)
	for {
		decoder.Decode(&myStruct)
	}
}

服务端在一个for循环中使用一个自定义结构体myStruct接收数据,客户端发送三次数据,myStruct.id分别为0,2,0,然而服务端接收到的数据为0,2,2,第三次的零值被覆盖了。
原因: gob传输时会省略零值,而我们是重复向同一个myStruct赋值,因此第二次传输后myStruct.id变为2,第三次传输的零值被省略,看起来就是服务端第三次接收到了2.
解决方法: 两种方法任选其一

  1. id从1开始编码,不使用零值。
  2. 在for循环内部定义myStruct

3.gob读取多余数据

场景: 客户端发送了两个数据ab,服务端使用gob.Decoder接收a,使用net.Conn.Read()接收b,b无法被正确接收。
原因:

// NewDecoder returns a new decoder that reads from the io.Reader.
// If r does not also implement io.ByteReader, it will be wrapped in a
// bufio.Reader.
func NewDecoder(r io.Reader) *Decoder {
	dec := new(Decoder)
	// We use the ability to read bytes as a plausible surrogate for buffering.
	if _, ok := r.(io.ByteReader); !ok {
		r = bufio.NewReader(r)
	}
	dec.r = r
	dec.wireType = make(map[typeId]*wireType)
	dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine)
	dec.ignorerCache = make(map[typeId]**decEngine)
	dec.countBuf = make([]byte, 9) // counts may be uint64s (unlikely!), require 9 bytes

	return dec
}

在gob源码中,NewDecoder函数会将用户传入的io.Reader包装成io.ByteReaderio.ByteReader会将原io.Reader中的数据全部读取到缓冲区中,后续读取数据时从缓冲区读取指定长度的数据。因此我们的客户端发送的数据b会被存入gob.Decoderio.ByteReader的缓冲区中,无法再被其他函数读取。

解决方法: 在设计传输协议时,保证在使用gob传输阶段,不会传输多余数据。举个栗子,在上面的场景中,客户端向服务端发送a后,先等待从服务端接收c后,再向服务端发送b

标签:记录,myStruct,gob,io,decoder,dec,服务端
From: https://blog.csdn.net/lfwxyC/article/details/137584310

相关文章

  • 一些记录
    this关键字当前实例的引用:this关键字用于指代当前对象的实例。区分成员变量和局部变量:当成员变量与局部变量重名时,可以使用this来区分成员变量。例如,在构造器或方法中,this.variable指的是当前实例的成员变量variable,而简单的variable指的是局部变量。在构造器中调用其......
  • 蓝桥杯真题代码记录(最优清零方案
    目录1.题目:2.我的代码:小结:1.题目:给定一个长度为N的数列41,42,…,AN。现在小蓝想通过若干次操作将这个数列中每个数字清零。每次操作小蓝可以选择以下两种之一:1.选择一个大于0的整数,将它减去1;2.选择连续区个大于0的整数,将它们各减去1。小蓝最少经......
  • npm(Node Package Manager) 学习记录
    一、npm是什么npm是Node.js包管理器。是一个命令行工具,用于安装和管理Node.js项目中的代码库和工具。npm允许从npm注册表(一个大型的软件包数据库)中搜索、安装、更新和删除软件包,并处理这些软件包的依赖关系。npm已经成为Node.js生态系统中不可或缺的一部分,通......
  • CF&At记录1
    CF1916第一次熬夜打CF,感觉还行,可能是晚上人比较平静,思路就比较清晰。A本来是没什么要说的,但是傻了没开longlong,喜提FST!B题最开始想复杂了,开始慌了,但是静下来想想就发现只有两种情况,分类讨论一下就出来了。D题什么人类智慧题,幸好样例的给了提示,不然真不一定出的来。这......
  • goby 插件推荐 及 内网下载使用
    背景:在内网电脑上,配置,插件发现没有网络推荐插件:ExportCsvhttps://github.com/gobysec/GobyExtension/tree/master/samples/ExportCsv   推荐使用git 下载:没找到连接。。。另辟蹊径:把所有的插件都下载下来了   https://github.com/gobysec/GobyExtension ......
  • 月或季持续更新中!!!记录过敏性鼻炎治疗踩过的坑!
      目前实测无效的有:西药区药名     靠谱程度(0-100)辅舒良    50(前期有效果,感冒的时候别用浪费钱,前期神中神,后期丐中丐。评价:不如空气)生理盐水   20(知乎百度专家以及抖音强推,衍生出各种流派,但我真想给0分,我的文章我做主)各种凝胶   -999999分(智......
  • ROT 复现踩坑记录
    复现了很长很长时间……终于能跑出来了。记录一下有哪些需要注意的地方。由于自己之前完全没有任何服务器跑代码的经验,于是过程比较的痛苦。。。torch安装这b玩意捣鼓了半天。。主要就两个点要选择不高于当前服务器支持的cuda版本的torch。比如服务器cuda=11.6,那我......
  • AGC022F 做题记录
    link很牛逼的题目。操作\(A,B\),考虑从\(A\)向\(B\)连一条边,最终形成一棵内向有根树。所有次项的系数都是\(2^p(-1)^q\)的形式。对于树上的一个点\(u\),不难发现\(u\)的深度是\(2\)的次数。设\(c_{d,0/1}\)表示深度为\(d\)的点中系数为\(1/-1\)的点的个数,那么......
  • 2024年4月 杂题记录
    P10322高洁(Purity)设\(d=\prodp_i^{c_i}\),容易发现当\(d\midi^k\)时,\(i^k\)的所有质因子的幂次都不小于\(d\)的所有所有质因子的幂次,即\(i^k\)含有的质因子的幂次至少为\(\lceilc_i/k\rceil\),因此我们设\[f_k(d)=\prodp_i^{\lceilc_i/k\rceil}\]那么就有\(d\mid......
  • 井字棋-C语言(学习记录)
     一:游戏简介     井字棋,英文名叫Tic-Tac-Toe,是一种在3*3格子上进行的连珠游戏,和五子棋类似,由于棋盘一般不画边框,格线排成井字故得名。游戏需要的工具仅为纸和笔,然后由分别代表O和X的两个游戏者轮流在格子里留下标记(一般来说先手者为X),任意三个标记形成一条直线,则为获......