英文:
Golang packet strcuture returning buffer
问题
我已经创建了一个带有包结构的数据包包装器,如下所示:
// 数据包缓冲对象
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) {
// 将整数转换为字节
b := make([]byte, 2)
binary.LittleEndian.PutUint16(b, uint16(i_))
// 将字节写入缓冲区
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) {
// 显示新连接的来源
session.connection = conn
fmt.Println("Client connected from:", session.connection.RemoteAddr())
// 设置用户连接变量为true
session.isConnected = true
// 发送握手包
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{}
// 创建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")
}
// 创建数据包
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 是正确的方法吗?还是我在处理方式上完全错误了?
英文:
I have made a packet package with a packet structure inside like so:
//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)
}
This is the session package that uses the packet structure to form packets and send them to the client
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)
}
This is the MaplePacket package that creates the packets to send to the client that are requested from the session package
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()
}
However when creating a packet like in the example above and adding values, the Packet.GetBytes() returns an empty array. Is bytes.Buffer the correct way to go about this is? Or am I going completely wrong in how I am approaching this?
答案1
得分: 6
Go通过值传递的方式传递所有参数,包括接收器。
尝试使用指针接收器:(p *Packet)
。bytes.Buffer
包含被丢弃的状态信息。
你的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
类型的变量的副本(按值)传递给方法。副本会被更新以反映新的状态,并在返回后被丢弃。
英文:
Go passes all arguments, including receivers, by value.
Try using pointer receivers: (p *Packet)
. bytes.Buffer
contains state information which is being discarded.
> 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.
Your type Package
type is equivalent to the following.
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.
}
You pass a copy (by value) of a Package
type variable to the methods. The copy is updated to reflect the new state and, upon return is discarded.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论