我在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)
}
}
Run Code Online (Sandbox Code Playgroud)
这是客户端代码:
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)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*elf 14
如您所料,由于UDP的性质,似乎UDP丢包.由于UDP是无连接的,因此客户端不关心服务器是否可用或准备好接收数据.因此,如果服务器正忙于处理,则无法处理下一个传入的数据报.您可以检查netstat -u(应包括UDP数据包丢失信息).我遇到了同样的事情,服务器(接收方)无法跟上发送的数据包.
你可以尝试两件事(第二件事就是你的例子):
调用SetReadBuffer.确保接收套接字有足够的缓冲来处理您抛出的所有内容.
sock, _ := net.ListenUDP("udp", addr)
sock.SetReadBuffer(1048576)
Run Code Online (Sandbox Code Playgroud)
在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)
}
Run Code Online (Sandbox Code Playgroud)
...
go handlePacket(buf, rlen, i)
Run Code Online (Sandbox Code Playgroud)
最后一个选择:
最后,可能不是你想要的,你在你的客户端睡一觉,这会降低速度并且也会解决问题.例如
buf := []byte("bla bla bla I am the packet")
time.Sleep(100 * time.Millisecond)
_, err := con.Write(buf)
Run Code Online (Sandbox Code Playgroud)