我已经在内部创建了一个包结构的数据包:
//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正确的方法来解决这个问题吗?或者我在接近这个方面我完全错了?
答案 0 :(得分:6)
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. }
Go编程语言
方法
关于接收器的指针与值的规则是值方法 可以在指针和值上调用,但指针方法只能是 在指针上调用。这是因为指针方法可以修改 接收器;在值的副本上调用它们会导致这些 修改被丢弃。
您的类型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
类型变量的副本(按值)传递给方法。更新副本以反映新状态,并在返回时被丢弃。