大佬教程收集整理的这篇文章主要介绍了golang -- 网络字节编解码(1),大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
在网络传输协议过程中,封包常见的方式一般是:
①头标识+数据头(类型/属性/数据长度)+数据体+尾标识 -->一般还需要转义
②固定长度 --> 编解码方便,浪费宽带
③通过结尾标识(eg.通过base64传输,以\0结束) -->编解码方便,浪费 宽带
下面是golang在编解码的常用手段
@H_618_19@解码
首先需要把[]byte的ascii串转化为uint8,uint16,uint32,uint64等 (分别对应python的B,H,I,Q).特别要注意大端和小端对齐方式(python大端">",小端"<",这里也用它们的ascii吧)
//这是一个例子,解码出">HHI" funcunpack(data[]byte,edianbytE)(uint16,[]bytE){ dataType:=ToUInt16(data[0:2],edian) dataAttr:=ToUInt16(data[2:4],edian) dataLen:=ToUInt32(data[4:8],edian) extra:=data[8:] returndataType,dataAttr,dataLen,extra } funcToUInt8(buf[]byte,edianbytE)uint8{ //len(buf)==1-->B t:=uint8(buf[0]) returnt } funcToUInt16(buf[]byte,edianbytE)uint16{ //len(buf)==2-->H t:=uint16(buf[0]) ifedian==62{//">" t=t<<8|uint16(buf[1]) }elseifedian==60{//"<" t=t|uint16(buf[1])<<8 } returnt } funcToUInt32(buf[]byte,edianbytE)uint32{ //len(buf)==4-->I t:=uint32(buf[0]) ifedian==62{ t=t<<24 t=t|uint32(buf[1])<<16 t=t|uint32(buf[2])<<8 t=t|uint32(buf[3]) }elseifedian==60{ t=t|uint32(buf[1])<<8 t=t|uint32(buf[2])<<16 t=t|uint32(buf[3])<<24 } returnt } funcToUInt64(buf[]byte,edianbytE)uint64{ //len(buf)==8-->Q t:=uint64(buf[0]) ifedian==62{ t=t<<56 t=t|uint64(buf[1])<<48 t=t|uint64(buf[2])<<40 t=t|uint64(buf[3])<<32 t=t|uint64(buf[4])<<24 t=t|uint64(buf[5])<<16 t=t|uint64(buf[6])<<8 t=t|uint64(buf[7]) }elseifedian==60{ t=t|uint64(buf[1])<<8 t=t|uint64(buf[2])<<16 t=t|uint64(buf[3])<<24 t=t|uint64(buf[4])<<32 t=t|uint64(buf[5])<<40 t=t|uint64(buf[6])<<48 t=t|uint64(buf[7])<<56 } returnt }
@H_618_19@编码
解码的逆过程,把uint8,uint32转化为[]byte -->ascii slice
//这是一个例子,编码为">HHI" funcpack(dataTypeuint16,dataAttruint16,dataLenuint32)[]byte{ buf:=make([]byte,8) PutUInt16(dataType,buf[0:2],62) PutUInt16(dataAttr,buf[2:4],62) PutUInt32(dataLen,buf[4:8],62) //buf=bufType+bufAttr+bufLen returnbuf } funcputUInt8(numuint8,buf[]byte,edianbytE){ //len(buf)==1 buf[0]=byte(num) } funcputUInt16(numuint16,edianbytE){ //len(buf)==2 buf[0]=byte(num>>8) buf[1]=byte(num) ifedian==62{//">" }elseifedian==60{//"<" buf[0]^=buf[1] buf[1]^=buf[0] buf[0]^=buf[1] } } funcputUInt32(numuint32,edianbytE){ //len(buf)==4 buf[0]=byte(num>>24) buf[1]=byte(num>>16) buf[2]=byte(num>>8) buf[3]=byte(num) ifedian==62{ }elseifedian==60{ buf[0]^=buf[3] buf[3]^=buf[0] buf[0]^=buf[3] buf[1]^=buf[2] buf[2]^=buf[1] buf[1]^=buf[2] } } funcputUInt64(numuint64,edianbytE){ //len(buf)==8 ifedian==62{ buf[0]=byte(num>>56) buf[1]=byte(num>>48) buf[2]=byte(num>>40) buf[3]=byte(num>>32) buf[4]=byte(num>>24) buf[5]=byte(num>>16) buf[6]=byte(num>>8) buf[7]=byte(num) }elseifedian==60{ buf[0]=byte(num) buf[1]=byte(num>>8) buf[2]=byte(num>>16) buf[3]=byte(num>>24) buf[4]=byte(num>>32) buf[5]=byte(num>>40) buf[6]=byte(num>>48) buf[7]=byte(num>>56) } }
以上是大佬教程为你收集整理的golang -- 网络字节编解码(1)全部内容,希望文章能够帮你解决golang -- 网络字节编解码(1)所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。