標籤:
寫得不完善也不完美 尤其是高低位轉換那(go和c 二進位高地位相反 需要轉換,還有go int轉[]byte長度是4位),希望牛人看後指導一下
項目需要通過socket調取 用戶端是go ,伺服器端是python,由於需要封包解包,就參照python寫的
python 的pack/unpack 參考 Python使用struct處理二進位(pack和unpack用法)
package includesimport ( "bytes" "encoding/binary" "fmt" _ "os" "strconv" "strings")type Protocol struct { Format []string}//封包func (p *Protocol) Pack(args ...interface{}) []byte { la := len(args) ls := len(p.Format) ret := []byte{} if ls > 0 && la > 0 && ls == la { for i := 0; i < ls; i++ { if p.Format[i] == "H" { ret = append(ret, IntToBytes2(args[i].(int))...) } else if p.Format[i] == "I" { ret = append(ret, IntToBytes4(args[i].(int))...) } else if strings.Contains(p.Format[i], "s") { num, _ := strconv.Atoi(strings.TrimRight(p.Format[i], "s")) ret = append(ret, []byte(fmt.Sprintf("%s%s", args[i].(string), strings.Repeat("\x00", num-len(args[i].(string)))))...) } } } return ret}//解包func (p *Protocol) UnPack(msg []byte) []interface{} { la := len(p.Format) ret := make([]interface{}, la) if la > 0 { for i := 0; i < la; i++ { if p.Format[i] == "H" { ret[i] = Bytes4ToInt(msg[0:2]) msg = msg[2:len(msg)] } else if p.Format[i] == "I" { ret[i] = Bytes4ToInt(msg[0:4]) msg = msg[4:len(msg)] } else if strings.Contains(p.Format[i], "s") { num, _ := strconv.Atoi(strings.TrimRight(p.Format[i], "s")) ret[i] = string(msg[0:num]) msg = msg[num:len(msg)] } } } return ret}func (p *Protocol) Size() int { size := 0 ls := len(p.Format) if ls > 0 { for i := 0; i < ls; i++ { if p.Format[i] == "H" { size = size + 2 } else if p.Format[i] == "I" { size = size + 4 } else if strings.Contains(p.Format[i], "s") { num, _ := strconv.Atoi(strings.TrimRight(p.Format[i], "s")) size = size + num } } } return size}//整形轉換成位元組func IntToBytes(n int) []byte { m := int32(n) bytesBuffer := bytes.NewBuffer([]byte{}) binary.Write(bytesBuffer, binary.BigEndian, m) gbyte := bytesBuffer.Bytes() return gbyte}//整形轉換成位元組4位func IntToBytes4(n int) []byte { m := int32(n) bytesBuffer := bytes.NewBuffer([]byte{}) binary.Write(bytesBuffer, binary.BigEndian, m) gbyte := bytesBuffer.Bytes() //c++ 高低位轉換 k := 4 x := len(gbyte) nb := make([]byte, k) for i := 0; i < k; i++ { nb[i] = gbyte[x-i-1] } return nb}//整形轉換成位元組2位func IntToBytes2(n int) []byte { m := int32(n) bytesBuffer := bytes.NewBuffer([]byte{}) binary.Write(bytesBuffer, binary.BigEndian, m) gbyte := bytesBuffer.Bytes() //c++ 高低位轉換 k := 2 x := len(gbyte) nb := make([]byte, k) for i := 0; i < k; i++ { nb[i] = gbyte[x-i-1] } return nb}//位元組轉換成整形func BytesToInt(b []byte) int { bytesBuffer := bytes.NewBuffer(b) var x int32 binary.Read(bytesBuffer, binary.BigEndian, &x) return int(x)}//4個位元組轉換成整形func Bytes4ToInt(b []byte) int { xx := make([]byte, 4) if len(b) == 2 { xx = []byte{b[0], b[1], 0, 0} } else { xx = b } m := len(xx) nb := make([]byte, 4) for i := 0; i < 4; i++ { nb[i] = xx[m-i-1] } bytesBuffer := bytes.NewBuffer(nb) var x int32 binary.Read(bytesBuffer, binary.BigEndian, &x) return int(x)}
調用
p := new(Protocol)p.Format = []string{"H", "H", "I", "16s", "I", "I", "I"}h_byte := p.Pack(1, 1, 1, "abc", 1, 0, len(request_buf))conn.Write(h_byte)
附加:
int 轉 二進位 fmt.Printf("%08b\n", 97) // 01100001二進位轉int i, _ := strconv.ParseInt("1100001", 2, 32) //97int 轉 []byte IntToBytes(1000) // [0 0 3 232] 3*256+232=1000func IntToBytes(n int) []byte {m := int32(n)bytesBuffer := bytes.NewBuffer([]byte{})binary.Write(bytesBuffer, binary.BigEndian, m)gbyte := bytesBuffer.Bytes()return gbyte}[]byte 轉int BytesToInt([]byte{0,0,3,232}) //1000func BytesToInt(b []byte) int {bytesBuffer := bytes.NewBuffer(b)var x int32binary.Read(bytesBuffer, binary.BigEndian, &x)return int(x)}int 轉 byte byte(97) //97
golang 仿python pack/unpack