我制作了一个数据包包,里面有一个数据包结构:
//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
包含被丢弃的状态信息。
// 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
Methods
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/