tcp傳輸的資料是以流的形式傳輸的,因此就沒有辦法判斷到哪里結束算是自己的一個訊息,這樣就會出現粘包問題,多個包粘在一起了
可以使用這樣一個自定義的形式來解決,一個訊息分為 head+body head包括資料的長度和資料編號 , 長度和編號都是uint32型別 也就是32位 占有4個位元組 , 總共head占有8個位元組
封裝一個訊息的結構體,作為一個資料物體,比如下面這個,編號 資料 資料長度 三個屬性
package znettype Message struct { Id uint32 Data []byte MsgLen uint32}func NewMessage() *Message { m := &Message{} return m}func (m *Message) GetId() uint32 { return m.Id}func (m *Message) GetData() []byte { return m.Data}func (m *Message) GetMsgLen() uint32 { return m.MsgLen}func (m *Message) SetId(id uint32) { m.Id = id}func (m *Message) SetData(data []byte) { m.Data = data}func (m *Message) SetMsgLen(len uint32) { m.MsgLen = len}
封裝一個封包解包的結構體,包括封包和解包的方法,封包就是先寫長度,再寫編號,再寫資料;解包只是獲取下長度和編號,資料下次再取
package znetimport "zinx/zinterface"import "bytes"import "encoding/binary"type DataPack struct {}func NewDataPack() *DataPack { dp := &DataPack{} return dp}func (dp *DataPack) Pack(m zinterface.IMessage) ([]byte, error) { dataBuff := bytes.NewBuffer([]byte{}) binary.Write(dataBuff, binary.LittleEndian, m.GetMsgLen()) binary.Write(dataBuff, binary.LittleEndian, m.GetId()) binary.Write(dataBuff, binary.LittleEndian, m.GetData()) return dataBuff.Bytes(), nil}func (dp *DataPack) Unpack(d []byte) (zinterface.IMessage, error) { m := NewMessage() r := bytes.NewReader(d) binary.Read(r, binary.LittleEndian, &m.MsgLen) binary.Read(r, binary.LittleEndian, &m.Id) return m, nil}
測驗,先封包再解包
body:=[]byte("nihao") m:=znet.NewMessage() m.SetId(888) m.SetData(body) m.SetMsgLen(uint32(len(body))) log.Println(m) dp:=znet.NewDataPack() dataPack,_:=dp.Pack(m) log.Println(dataPack) m2,_:=dp.Unpack(dataPack) log.Println(m2)
2019/12/17 15:42:30 &{888 [110 105 104 97 111] 5}
2019/12/17 15:42:30 [5 0 0 0 120 3 0 0 110 105 104 97 111]
2019/12/17 15:42:30 &{888 [] 5}
結果就是上面的樣子,解出來就可以去用了
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/55029.html
標籤:Go
上一篇:新人求助,如何用Python求一個24小時每分鐘采樣的資料 的每八小時的均值
下一篇:go 中recover捕獲例外
