3.记一个go语言字节数组和结构体转换:binary-obiect(obj的结构为byte)

//代码段一:message的占用空间大小固定
package main

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

type message struct{
	id int32
	len int32
	data [4]byte //这个也可以是切片,但是如果是切片,需要解两次才能解成msg对象
}
type pack struct{

}

func(pck *pack)pack(data []byte) *message{
	msg := &message{}
	dataio := bytes.NewReader(data)


	//:对于data这个字节数组,从低字节开始读,把读到的字节放进msg.len的地址为首的空间,因为这个空间就4个字节(int32)故而会读走4个字节
//!!!!注意,binary.Read(XX,XX,XX3) XX3这个地址对应的是一块空间,这就是为啥message结构体的第三个属性data我限定空间大小的原因
	//:dataio流的指向在读完之后,会指向data的倒数第5个字节
	binary.Read(dataio,binary.LittleEndian,&msg.id)
	binary.Read(dataio,binary.LittleEndian,&msg.len)
	binary.Read(dataio,binary.LittleEndian,&msg.data)
	fmt.Println("----",msg)

	return msg
}
func(pck *pack)unpack(msg *message) []byte{

	databufio := bytes.NewBuffer([]byte{})

	binary.Write(databufio,binary.LittleEndian,msg.id)
	binary.Write(databufio,binary.LittleEndian,msg.len)
	binary.Write(databufio,binary.LittleEndian,msg.data)
	return databufio.Bytes()
}


func main(){
	bindata := []byte{}
	msg := &message{
		id:1,
		len:4,
		data:[4]byte{'h','a','h','h'},
	}
	pck := &pack{}
	bindata = pck.unpack(msg)
	fmt.Println("msg - conv - bin-len:",len(bindata))
	fmt.Println(bindata)

	msg2 := pck.pack(bindata)

	fmt.Println("bin-conv-msg2-msg2.data=",msg2)
}

还有另外一种写法:

package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"unsafe"
)

type message struct{
	id int32
	len int32
	data []byte
}
type pack struct{

}

func(pck *pack)packHead(data []byte) *message{
	msg := &message{}
	dataio := bytes.NewReader(data)


	//:对于data这个字节数组,从低字节开始读,把读到的字节放进msg.len的地址为首的空间,因为这个空间就4个字节(int32)故而会读走4个字节
	//:dataio流的指向在读完之后,会指向data的倒数第5个字节
	binary.Read(dataio,binary.LittleEndian,&msg.id)
	binary.Read(dataio,binary.LittleEndian,&msg.len)
	//binary.Read(dataio,binary.LittleEndian,&msg.data)
	fmt.Println("----",msg)

	return msg
}
func(pck *pack)unpack(msg *message) []byte{

	databufio := bytes.NewBuffer([]byte{})

	binary.Write(databufio,binary.LittleEndian,msg.id)
	binary.Write(databufio,binary.LittleEndian,msg.len)
	binary.Write(databufio,binary.LittleEndian,msg.data)
	return databufio.Bytes()
}


func main(){
	bindata := []byte{}
	msg := &message{
		id:1,
		len:4,
		data:[]byte{'h','a','h','h'},
	}
	pck := &pack{}
	bindata = pck.unpack(msg)
	fmt.Println("msg - conv - bin-len:",len(bindata))
	fmt.Println(bindata)


	msg2 := pck.packHead(bindata)
	beginIndex := unsafe.Sizeof(msg2.id)+unsafe.Sizeof(msg2.len)
	msg2.data = make([]byte,4)
	binary.Read(bytes.NewReader(bindata[beginIndex:]),binary.LittleEndian,&msg2.data)
	fmt.Println("bin-conv-msg2-msg2.data=",msg2)
}

http是网络协议,解析包的方式

json,xml是数据协议,数据解析的格式

改变函数外部的数据用指针。

你可能感兴趣的:(提高篇-服务器开发)