从长度未知的UDP套接字读取数据

425*_*esp 5 sockets networking udp go

我怎么能socket.ReadFromUDP事先知道长度?现在我有这样的事情.

buff := make([]byte, <unknownLength>)
for {
    socket.ReadFromUDP(buff)
    fmt.Println("Bytes read:", buff.Len())
}
Run Code Online (Sandbox Code Playgroud)

我试过这个,但它总是读取1024个字节.

buff := make([]byte, 1024)
for {
    bytesRead, _, _ := socket.ReadFromUDP(buff)
    fmt.Println("Bytes read:", bytesRead)
}
Run Code Online (Sandbox Code Playgroud)

我从服务器收到的数据包从几个字节到几千字节不等.

Jim*_*imB 10

UDP套接字以离散数据报(因此名称SOCK_DGRAM)接收消息.虽然Go有一个相对干净的网络API,但你仍然无法在不了解底层套接字的情况下离开(在我的套接字库中调用recv时,我的recv缓冲区应该有多大).

UDP套接字将Read达到接收缓冲区的大小,并将丢弃其余的,因此您无法像在TCP流上那样继续读取.UDP套接字上的单个接收消耗来自网络的单个数据报.

虽然UDP数据包的理论最大有效载荷是65,507,但实际上由于路径MTU限制,您可能不会获得超过1400字节的消息.如果你将缓冲区设置得比这大得多,就像4096字节一样,你将非常安全,但你可以使用64k缓冲区来确定.

虽然在Go中尝试确定待处理的数据包大小是不可行的,但您可以判断是否丢失了数据的价值:

oob := make([]byte, 1024)
n, on, flags, addr, err := c.ReadMsgUDP(buff, oob)
if flags & syscall.MSG_TRUNC != 0 {
    fmt.Println("truncated read")
}
Run Code Online (Sandbox Code Playgroud)