go1.11 net.UDPConn.close() 阻塞问题

版权声明:博客地址: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 {}

}

猜你喜欢

转载自blog.csdn.net/x356982611/article/details/82626608
今日推荐