以太坊 rlp使用,进行网络传输

0  协议

package protocol
type MsgHead struct {
    Len uint
    
}
type MsgBody struct {
    Msg string
}
type Msg struct {
    MsgHead
    MsgBody
}

1 服务器端代码

package main
import (
    "fmt"
    "net"
    "os"
    "protocol"
    rlp "github.com/ethereum/go-ethereum/rlp"
)
func main(){
    service := "127.0.0.1:8080"
    listener , err := net.Listen("tcp", service)
    if err != nil {
        fmt.Println(err)
    }
    for {
        conn, err := listener.Accept()
        if err != nil {
            fmt.Println(err)
        }
        //
        strmsg := "asked: Hello world"
        var msg protocol.Msg
        msg.MsgHead.Len = 32
        msg.MsgBody.Msg = strmsg

        buf, err := rlp.EncodeToBytes(msg)
        if err != nil {
            fmt.Println(err)
            os.Exit(0)
        }
        _, err = conn.Write(buf)
        if err != nil {
            fmt.Println(err)
        }

    }

}

2 客户端代码

package main
import (
    "fmt"
    "net"
    "protocol"
    rlp "github.com/ethereum/go-ethereum/rlp"
)
func main(){
    service := "127.0.0.1:8080"
    conn, err := net.Dial("tcp", service)
    defer conn.Close()
    if err != nil {
        fmt.Println(err)
    }
    
        c := make([]byte,1024)
    nbytes, err:=    conn.Read(c)
    if err != nil {
        fmt.Println(err)
    }
    
    M := c[:nbytes]
    T := protocol.Msg{}
    err = rlp.DecodeBytes(M, &T)
    if err != nil {
        fmt.Println(err)
    }    
    fmt.Printf("%d,%s\n", T.Len,T.Msg)
    

}

3 知识

RLP (递归长度前缀)提供了一种适用于任意二进制数据数组的编码,RLP已经成为以太坊中对对象进行序列化的主要编码方式。RLP的唯一目标就是解决结构体的编码问题;对原子数据类型(比如,字符串,整数型,浮点型)的编码则交给更高层的协议;以太坊中要求数字必须是一个大端字节序的、没有零占位的存储的格式(也就是说,一个整数0和一个空数组是等同的)。

/*
rlp包用法
rlp目的是可以将常用的数据结构,uint,string,[]byte,struct,slice,array,big.int等序列化以及反序列化.
要注意的是rlp特别不支持有符号数的序列化
具体用法见下
*/
//编码
type TestRlpStruct struct {
    A      uint
    B      string
    C      []byte
    BigInt *big.Int
}

//rlp用法
func TestRlp(t *testing.T) {
    //1.将一个整数数组序列化
    arrdata, err := rlp.EncodeToBytes([]uint{32, 28})
    fmt.Printf("unuse err:%v\n", err)
    //fmt.Sprintf("data=%s,err=%v", hex.EncodeToString(arrdata), err)
    //2.将数组反序列化
    var intarray []uint
    err = rlp.DecodeBytes(arrdata, &intarray)
    //intarray 应为{32,28}
    fmt.Printf("intarray=%v\n", intarray)

    //3.将一个布尔变量序列化到一个writer中
    writer := new(bytes.Buffer)
    err = rlp.Encode(writer, true)
    //fmt.Sprintf("data=%s,err=%v",hex.EncodeToString(writer.Bytes()),err)
    //4.将一个布尔变量反序列化
    var b bool
    err = rlp.DecodeBytes(writer.Bytes(), &b)
    //b:true
    fmt.Printf("b=%v\n", b)

    //5.将任意一个struct序列化
    //将一个struct序列化到reader中
    _, r, err := rlp.EncodeToReader(TestRlpStruct{3, "44", []byte{0x12, 0x32}, big.NewInt(32)})
    var teststruct TestRlpStruct
    err = rlp.Decode(r, &teststruct)
    //{A:0x3, B:"44", C:[]uint8{0x12, 0x32}, BigInt:32}
    fmt.Printf("teststruct=%#v\n", teststruct)

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值