function - Golang 包结构返回缓冲区

标签 function struct go byte packet

我制作了一个数据包包,里面有一个数据包结构:

//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)
}

这是session包,使用packet结构组成包发送给客户端

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 包,它创建从 session 包请求发送到客户端的数据包

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 是解决这个问题的正确方法吗?还是我的处理方式完全错误?

最佳答案

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.
}

The Go Programming Language

Effective Go

Methods

Pointers vs. Values

The rule about pointers vs. values for receivers is that value methods can be invoked on pointers and values, but pointer methods can only be invoked on pointers. This is because pointer methods can modify the receiver; invoking them on a copy of the value would cause those modifications to be discarded.

您的类型 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 类型变量的副本(按值)传递给方法。更新副本以反射(reflect)新状态,并在返回时丢弃。

关于function - Golang 包结构返回缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23970090/

相关文章:

javascript - 将 PHP var 传递给 js 函数

c++ - 在头文件中使用时无法识别结构

docker - Docker Go SDK ContainerExecAttach返回时间戳

go - 缓冲的 golang channel 丢失数据

c++ - 通过复制返回局部变量 - 它是如何工作的

javascript - 点击 jQuery 不工作 FireFox - 可能是 event.preventdefault

c++ - 为什么 "char"在结构类型中是一个糟糕的编程习惯?

java - 为什么不能在 Java 中对空指针调用方法?

c++ - 编写此算法的更有效方法?

我可以在 C 结构中声明结构引用的动态数组吗?