gpt4 book ai didi

networking - golang UDP服务器的奇怪行为

转载 作者:IT老高 更新时间:2023-10-28 13:10:12 26 4
gpt4 key购买 nike

我在 go 中编写了一个简单的 UDP 服务器。

当我执行 go run udp.go 时,它会打印我发送给它的所有包。但是当运行 go run udp.go > out 时,它会在客户端停止时停止将 stdout 传递给 out 文件。

客户端是发送 10k 个请求的简单程序。所以在文件中我有大约 50% 的已发送包。当我再次运行客户端时,out 文件再次增长,直到客户端脚本完成。

服务器代码:

package main

import (
"net"

"fmt"
)

func main() {
addr, _ := net.ResolveUDPAddr("udp", ":2000")
sock, _ := net.ListenUDP("udp", addr)

i := 0
for {
i++
buf := make([]byte, 1024)
rlen, _, err := sock.ReadFromUDP(buf)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(buf[0:rlen]))
fmt.Println(i)
//go handlePacket(buf, rlen)
}
}

这是客户端代码:

package main

import (
"net"

"fmt"
)

func main() {

num := 0
for i := 0; i < 100; i++ {
for j := 0; j < 100; j++ {
num++
con, _ := net.Dial("udp", "127.0.0.1:2000")
fmt.Println(num)
buf := []byte("bla bla bla I am the packet")
_, err := con.Write(buf)
if err != nil {
fmt.Println(err)
}
}
}
}

最佳答案

正如您所怀疑的,由于 UDP 的性质,这似乎是 UDP 数据包丢失。因为 UDP 是无连接的,所以客户端不关心服务器是否可用或准备好接收数据。因此,如果服务器正忙于处理,它将无法处理下一个传入的数据报。您可以使用 netstat -u 进行检查(其中应包括 UDP 数据包丢失信息)。我遇到了同样的事情,服务器(接收端)无法跟上发送的数据包。

您可以尝试两件事(第二件事对我有用):

调用 SetReadBuffer。确保接收套接字有足够的缓冲来处理你扔给它的所有东西。

sock, _ := net.ListenUDP("udp", addr)
sock.SetReadBuffer(1048576)

在一个 go 例程中处理所有数据包。 通过确保服务器在您希望它可以接收时不忙于做其他工作来尝试增加每秒的数据报。即,将处理工作转移到 go 例程中,因此您不会阻止 ReadFromUDP()。

//Reintroduce your go handlePacket(buf, rlen) with a count param
func handlePacket(buf []byte, rlen int, count int)
fmt.Println(string(buf[0:rlen]))
fmt.Println(count)
}

...

go handlePacket(buf, rlen, i)

最后一个选项:

最后,可能不是您想要的,您让您的客户端休眠,这会减慢速度并消除问题。例如

buf := []byte("bla bla bla I am the packet")
time.Sleep(100 * time.Millisecond)
_, err := con.Write(buf)

关于networking - golang UDP服务器的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19658052/

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