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

最近发现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 {}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值