gpt4 book ai didi

tcp - Go中读取完整网络PDU的方法

转载 作者:IT王子 更新时间:2023-10-29 02:17:19 24 4
gpt4 key购买 nike

我正在开发一个简单的 Go 服务器程序,它接收客户的请求并处理它。代码简化为:

package main

import (
"fmt"
"net"
"os"
)

const (
pduLen = 32
)

func checkError(err error) {
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}

func main() {
var buffer [4096]byte
var count int

conn, err := net.Dial("tcp", fmt.Sprintf("%s:%s", os.Args[1], os.Args[2]))
checkError(err)

for count < pduLen {
n, err := conn.Read(buffer[count:])
checkError(err)
count += n
}
......

}

我假设每个请求的长度都是32 字节(只是一个例子)。因为TCP是一个流协议(protocol),所以我需要用一个循环来检查是否读取了一个完整的PDU:

for count < pduLen {
n, err := conn.Read(buffer[count:])
checkError(err)
count += n
}

是否有任何方法可以确保读取完整的 PDU?我个人认为循环代码有点难看。

最佳答案

这可能取决于您收到的 PDU 的确切性质,但是 this example将查找大小,然后读取所有内容(使用 io.ReadFul() )。

func read(conn net.Conn, key string) string {
fmt.Fprintf(conn, GenerateCommand(OP_GET, key))
if verify(conn) {
var size uint16
binary.Read(conn, binary.LittleEndian, &size)
b := make([]byte, size)
// _, err := conn.Read(b)
_, err := io.ReadFull(conn, b)
if err == nil {
return string(b)
}
}
return ""
}

func verify(conn net.Conn) bool {
b := make([]byte, 1)
conn.Read(b)
return b[0] == ERR_NO_ERROR
}

用于:

conn, err := net.Dial("tcp", ":12345")
if err != nil {
t.Error(err)
}
write(conn, "foo", "bar")
if !verify(conn) {
t.Error("Bad write!")
}
if r := read(conn, "foo"); r != "bar" {
t.Errorf("Bad read! Got %v", r)
}

关于tcp - Go中读取完整网络PDU的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23775814/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com