写得不完善也不完美 尤其是高低位转换那(go和c 二进制高地位相反 需要转换,还有go int转[]byte长度是4位),希望牛人看后指导一下

项目需要通过socket调取 客户端是go ,服务器端是python,由于需要封包解包,就参照python写的

python 的pack/unpack 参考  Python使用struct处理二进制(pack和unpack用法)

package includes

import (
"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 > && la > && ls == la {
for i := ; 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 > {
for i := ; i < la; i++ {
if p.Format[i] == "H" {
ret[i] = Bytes4ToInt(msg[:])
msg = msg[:len(msg)]
} else if p.Format[i] == "I" {
ret[i] = Bytes4ToInt(msg[:])
msg = msg[:len(msg)]
} else if strings.Contains(p.Format[i], "s") {
num, _ := strconv.Atoi(strings.TrimRight(p.Format[i], "s"))
ret[i] = string(msg[:num])
msg = msg[num:len(msg)] }
}
}
return ret
} func (p *Protocol) Size() int {
size :=
ls := len(p.Format)
if ls > {
for i := ; i < ls; i++ {
if p.Format[i] == "H" {
size = size +
} else if p.Format[i] == "I" {
size = size +
} 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 :=
x := len(gbyte)
nb := make([]byte, k)
for i := ; i < k; i++ {
nb[i] = gbyte[x-i-]
}
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 :=
x := len(gbyte)
nb := make([]byte, k)
for i := ; i < k; i++ {
nb[i] = gbyte[x-i-]
}
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, )
if len(b) == {
xx = []byte{b[], b[], , }
} else {
xx = b
} m := len(xx)
nb := make([]byte, )
for i := ; i < ; i++ {
nb[i] = xx[m-i-]
}
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(, , , "abc", , , len(request_buf))
conn.Write(h_byte)

附加:

int 转 二进制 fmt.Printf("%08b\n", ) //

二进制转int i, _ := strconv.ParseInt("", , ) //

int 转 []byte IntToBytes() // [0 0 3 232]  3*256+232=1000

func 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{,,,}) // func BytesToInt(b []byte) int {
bytesBuffer := bytes.NewBuffer(b) var x int32
binary.Read(bytesBuffer, binary.BigEndian, &x) return int(x)
} int 转 byte byte() //

golang 仿python pack/unpack的更多相关文章

  1. python struct中的pack unpack

    python struct中的pack unpack pytyon tuple元组 print struct.unpack("!ihb", buffer)  结果为7 //pyth ...

  2. PHP: 深入pack/unpack

    https://my.oschina.net/goal/blog/195749 PHP作为一门为web而生的服务器端开发语言,被越来越多的公司所采用.其中不乏大公司,如腾迅.盛大.淘米.新浪等.在对性 ...

  3. PHP: 深入pack/unpack 字节序

    http://my.oschina.net/goal/blog/195749?p=1 目录[-] 写在前面的话 什么是字节序 MSB和LSB 大端序 小端序 网络字节序 主机字节序 总结 pack/u ...

  4. [转]PHP: 深入pack/unpack

    From : http://my.oschina.net/goal/blog/195749 http://www.w3school.com.cn/php/func_misc_pack.asp PHP作 ...

  5. PHP: 深入pack/unpack <转> [链接]

    PHP: 深入pack/unpack PHP: chr和pack.unpack那些 PHP: pack/unpack补遗

  6. 2017年的golang、python、php、c++、c、java、Nodejs性能对比(golang python php c++ java Nodejs Performance)

    2017年的golang.python.php.c++.c.java.Nodejs性能对比 本人在PHP/C++/Go/Py时,突发奇想,想把最近主流的编程语言性能作个简单的比较, 至于怎么比,还是不 ...

  7. 2017年的golang、python、php、c++、c、java、Nodejs性能对比[续]

    2017年的golang.python.php.c++.c.java.Nodejs性能对比[续] 最近忙,这个话题放了几天,今天来个续集.   上篇传送门: 2017年的golang.python.p ...

  8. golang与python多线程的并发速度

    一.golang的代码 package main import ( "fmt" "time" ) func Text_goroute(a int, b int) ...

  9. 想涨工资吗?那就学习Scala,Golang或Python吧

    [编者按]据薪水调查机构 PayScale 提供的数据显示,掌握 Scala,Golang 和 Python 语言以及诸如 Apache Spark 之类的大数据技术,能带来最大的薪水提升.本文作者为 ...

随机推荐

  1. codeforces 814E An unavoidable detour for home

    题目链接 正解:$dp$. 感觉这道题就是中国象棋的加强版..我们要发现一些性质. 首先就是这个图肯定是一个按照$bfs$序分层的图,且每个点只往自己上面那一层连了一条边,每个点不可能向自己的上面超过 ...

  2. iOS 加载pdf格式的文件

    可以加载的方式比较多,暂时先总结两种: 本地先导入一份pdf文件 type 1: 利用UIWebView加载 UIWebView *webView = [[UIWebView alloc] initW ...

  3. java _this关键字的用法

    1:This关键字可以用于从一个构造方法调用另一个构造方法,可以用于避免重复代码 2:this的第二个用于this.xxx表示成员变量,成员变量的作用范围是  类   避免产生歧义 package c ...

  4. 算法 - 给出一个字符串str,输出包含两个字符串str的最短字符串,如str为abca时,输出则为abcabca

    今天碰到一个算法题觉得比较有意思,研究后自己实现了出来,代码比较简单,如发现什么问题请指正.思路和代码如下: 基本思路:从左开始取str的最大子字符串,判断子字符串是否为str的后缀,如果是则返回st ...

  5. wshShell.SendKeys模拟键盘操作

    Dim wshShellSet wshShell = CreateObject("Wscript.Shell")wshShell.SendKeys "{ENTER}&qu ...

  6. javascript实现jsonp跨域问题+原理

    在工作中往往存在跨域的问题 ,跨域是什么概念就不在这里了,搜这类问题的肯定已经知道了.下面直接探讨jsonp跨域原理 jspon跨域原理: 1.动态创建一个script标签 var script = ...

  7. Jstorm TimeCacheMap源代码分析

    /*** Eclipse Class Decompiler plugin, copyright (c) 2016 Chen Chao (cnfree2000@hotmail.com) ***/ pac ...

  8. linux内存管理---虚拟地址、逻辑地址、线性地址、物理地址的区别(一)

    分析linux内存管理机制,离不了上述几个概念,在介绍上述几个概念之前,先从<深入理解linux内核>这本书中摘抄几段关于上述名词的解释: 一.<深入理解linux内核>的解释 ...

  9. DML-修改

    一, 修改单表的记录 语法: update 表名 set 字段=值[where 筛选条件] 二,修改多表 update 表名 别名 inner/left/rigth join 表二 on 连接条件 s ...

  10. NodeJ node.js Koa2 跨域请求

    Koa2 .3 跨域请求 Haisen's  需求分析 (localhost:8080 = 前端  [请求]  localhost:8081 = 服务器 ) 1.一个前台    一个服务器    前台 ...