【问题标题】:Golang packet strcuture returning bufferGolang 包结构返回缓冲区
【发布时间】:2014-07-21 03:04:27
【问题描述】:

我做了一个包包,里面有这样的包结构:

//A packet buffer object
package Packet

import (
    "bytes"
    "encoding/binary"
)

type Packet struct {
    buffer bytes.Buffer
}

func (p Packet) GetBytes() []byte {
    return p.buffer.Bytes()
}

func (p Packet) AddString(s string) {
    p.buffer.Write([]byte(s))
}

func (p Packet) AddInt(i_ int) {
    //Convert int to byte
    b := make([]byte, 2)
    binary.LittleEndian.PutUint16(b, uint16(i_))
    //Push byte to buffer
    p.buffer.Write([]byte(b))
}

func (p Packet) AddByte(b []byte) {
    p.buffer.Write(b)
}

这是会话包,使用包结构形成包发送给客户端

package Session

type MapleSession struct {
    connection net.Conn
    EncryptIV, DecryptIV []byte
    isConnected bool
}

func (session *MapleSession) Run(conn net.Conn) { 
    //Display where the new connection is coming from
    session.connection = conn
    fmt.Println("Client connected from:", session.connection.RemoteAddr())

    //Set the user connected variable on
    session.isConnected = true

    //Send Handshake
    packet := MaplePacket.CreateHandShake(&session.EncryptIV, &session.DecryptIV, 40, "", []byte("0x05"))
    session.connection.Write(packet)
}

这是 MaplePacket 包,它创建从会话包请求的要发送到客户端的数据包

package MaplePacket

func CreateHandShake (eIV, dIV *[]byte, version int, location string, locale []byte) []byte{
    packet := Packet.Packet{}

    //Create IVs
    *eIV = (make([]byte, 4))
    n1, _ := rand.Read(*eIV)
    *dIV = (make([]byte, 4))
    n2, _ := rand.Read(*dIV)

    if (n1 + n2 < 8) {
        fmt.Println("Error in IV generation")
    }    

    //Create the packet
    packet.AddInt(version)
    packet.AddString(location)
    packet.AddByte(*dIV)
    packet.AddByte(*eIV)
    packet.AddByte(locale)

    fmt.Println(packet.GetBytes())

    return packet.GetBytes()
}

但是,当像上面的示例一样创建数据包并添加值时,Packet.GetBytes() 返回一个空数组。 bytes.Buffer 是解决这个问题的正确方法吗?还是我的处理方式完全错了?

【问题讨论】:

    标签: function struct go byte packet


    【解决方案1】:

    Go 按值传递所有参数,包括接收者。

    尝试使用指针接收器:(p *Packet)bytes.Buffer 包含被丢弃的状态信息。


    package bytes

    // Simple byte buffer for marshaling data.
    // A Buffer is a variable-sized buffer of bytes with Read and Write methods.
    // The zero value for Buffer is an empty buffer ready to use.
    type Buffer struct {
      buf       []byte            // contents are the bytes buf[off : len(buf)]
      off       int               // read at &buf[off], write at &buf[len(buf)]
      runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each WriteByte or Rune
      bootstrap [64]byte          // memory to hold first slice; helps small buffers (Printf) avoid allocation.
      lastRead  readOp            // last read operation, so that Unread* can work correctly.
    }
    

    Go 编程语言

    Effective Go

    方法

    Pointers vs. Values

    关于接收者的指针与值的规则是值方法 可以在指针和值上调用,但指针方法只能是 在指针上调用。这是因为指针方法可以修改 接收者;在值的副本上调用它们会导致那些 修改被丢弃。

    你的Package类型相当于下面的。

    type Packet struct {
        buffer /* bytes.Buffer */ struct {
        buf       []byte            // contents are the bytes buf[off : len(buf)]
        off       int               // read at &buf[off], write at &buf[len(buf)]
        runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each WriteByte or Rune
        bootstrap [64]byte          // memory to hold first slice; helps small buffers (Printf) avoid allocation.
        lastRead  readOp            // last read operation, so that Unread* can work correctly.
    }
    

    您将Package 类型变量的副本(按值)传递给方法。更新副本以反映新状态,并在返回时被丢弃。

    【讨论】:

    • 我终于明白你的意思了!感谢您的帮助。
    猜你喜欢
    • 2014-05-17
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    相关资源
    最近更新 更多