版权声明:博客地址:blog.csdn.net/x356982611,未经允许不得转载,不得转载,不得转载 https://blog.csdn.net/x356982611/article/details/82626608
最近发现1.11版本的 net.UDPConn关闭的时候会阻塞,而1.11之前的版本不阻塞,但是udp端口无法正常关闭,最后发现是下面代码
fd, _ := conn.File()
defer fd.Close()
这个调用导致的
package main
import (
"fmt"
"math/rand"
"net"
"time"
// "syscall"
)
func queryConnectionBufSize(conn *net.UDPConn) {
//这个调用会导致udp连接无法关闭
fd, _ := conn.File()
defer fd.Close()
var recvbufsize, sendbufsize int
// recvbufsize, _ = syscall.GetsockoptInt(int(fd.Fd()), syscall.SOL_SOCKET, syscall.SO_RCVBUF)
// sendbufsize, _ = syscall.GetsockoptInt(int(fd.Fd()), syscall.SOL_SOCKET, syscall.SO_SNDBUF)
fmt.Printf("%s UDP 接收缓存大小:%v 发送缓存大小:%v", conn.LocalAddr().String(), recvbufsize, sendbufsize)
}
func recvProc(proxyCoon *net.UDPConn) {
for {
buf := make([]byte, 1024)
_, _, err := proxyCoon.ReadFromUDP(buf[:])
if err != nil {
if nerr, ok := err.(net.Error); !ok || !nerr.Timeout() {
fmt.Println("接收UDP数据失败:", err.Error())
return
} else {
fmt.Println("超时:", err.Error())
return
}
}
}
}
func closeProc(proxyCoon *net.UDPConn) {
proxyCoon.Close()
}
func startListenServer() {
// rand.Seed(time.Now().Unix())
connUDP, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("0.0.0.0"), Port: rand.Intn(1000) + 21000})
if err != nil {
fmt.Println("监听UDP数据发送端口失败", err.Error())
return
} else {
fmt.Println("监听UDP数据发送端口成功")
}
connUDP.SetReadBuffer(1024 * 1024 * 10)
connUDP.SetWriteBuffer(1024 * 1024 * 10)
connUDP.SetReadDeadline(time.Now().Add(time.Second))
queryConnectionBufSize(connUDP)
go recvProc(connUDP)
time.Sleep(time.Second * 5)
go closeProc(connUDP)
}
func main() {
go startListenServer()
go startListenServer()
go startListenServer()
select {}
}