如何处理 go 中的粘性 tcp 数据包?
How to deal with sticky tcp packet in go?
我有一个 tcp 服务器和一个客户端,服务器执行以下操作
func providerCallback(conn net.Conn) {
reader := bufio.NewReader(conn)
var err error
for {
lenbyte, _ := reader.Peek(4)
reader.Discard(4)
slen := int(binary.BigEndian.Uint32(lenbyte))
data, err = reader.Peek(slen)
process(data)
reader.Discard(slen)
}
}
客户端发送数据包的速度似乎快于进程可以处理的速度,因此我想在 bufio 中缓冲请求并稍后处理。
但是,由于bufio的大小是固定的(4096,即使我可以增加它,它仍然是固定的),这意味着我不能手动Reset
它,因为可能会有一个数据包切割of在bufio的最后,如下
|normal data... [First 20 bytes of packet P] | [the rest of packet P]
|------------------- size of bufio ------------------|
如何拼接被切断的数据包,并将bufio重新用于以后的数据包?
例如,
import (
"bufio"
"encoding/binary"
"io"
"net"
)
func providerCallback(conn net.Conn) error {
rdr := bufio.NewReader(conn)
data := make([]byte, 0, 4*1024)
for {
n, err := io.ReadFull(rdr, data[:4])
data = data[:n]
if err != nil {
if err == io.EOF {
break
}
return err
}
dataLen := binary.BigEndian.Uint32(data)
if uint64(dataLen) > uint64(cap(data)) {
data = make([]byte, 0, dataLen)
}
n, err = io.ReadFull(rdr, data[:dataLen])
data = data[:n]
if err != nil {
return err
}
process(data)
}
return nil
}
func process([]byte) {}
我有一个 tcp 服务器和一个客户端,服务器执行以下操作
func providerCallback(conn net.Conn) {
reader := bufio.NewReader(conn)
var err error
for {
lenbyte, _ := reader.Peek(4)
reader.Discard(4)
slen := int(binary.BigEndian.Uint32(lenbyte))
data, err = reader.Peek(slen)
process(data)
reader.Discard(slen)
}
}
客户端发送数据包的速度似乎快于进程可以处理的速度,因此我想在 bufio 中缓冲请求并稍后处理。
但是,由于bufio的大小是固定的(4096,即使我可以增加它,它仍然是固定的),这意味着我不能手动Reset
它,因为可能会有一个数据包切割of在bufio的最后,如下
|normal data... [First 20 bytes of packet P] | [the rest of packet P]
|------------------- size of bufio ------------------|
如何拼接被切断的数据包,并将bufio重新用于以后的数据包?
例如,
import (
"bufio"
"encoding/binary"
"io"
"net"
)
func providerCallback(conn net.Conn) error {
rdr := bufio.NewReader(conn)
data := make([]byte, 0, 4*1024)
for {
n, err := io.ReadFull(rdr, data[:4])
data = data[:n]
if err != nil {
if err == io.EOF {
break
}
return err
}
dataLen := binary.BigEndian.Uint32(data)
if uint64(dataLen) > uint64(cap(data)) {
data = make([]byte, 0, dataLen)
}
n, err = io.ReadFull(rdr, data[:dataLen])
data = data[:n]
if err != nil {
return err
}
process(data)
}
return nil
}
func process([]byte) {}