github.com/gogf/gf/v2@v2.7.4/net/gudp/gudp_func.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gudp 8 9 import ( 10 "net" 11 12 "github.com/gogf/gf/v2/errors/gerror" 13 ) 14 15 // NewNetConn creates and returns a *net.UDPConn with given addresses. 16 func NewNetConn(remoteAddress string, localAddress ...string) (*net.UDPConn, error) { 17 var ( 18 err error 19 remoteAddr *net.UDPAddr 20 localAddr *net.UDPAddr 21 network = `udp` 22 ) 23 remoteAddr, err = net.ResolveUDPAddr(network, remoteAddress) 24 if err != nil { 25 return nil, gerror.Wrapf( 26 err, 27 `net.ResolveUDPAddr failed for network "%s", address "%s"`, 28 network, remoteAddress, 29 ) 30 } 31 if len(localAddress) > 0 { 32 localAddr, err = net.ResolveUDPAddr(network, localAddress[0]) 33 if err != nil { 34 return nil, gerror.Wrapf( 35 err, 36 `net.ResolveUDPAddr failed for network "%s", address "%s"`, 37 network, localAddress[0], 38 ) 39 } 40 } 41 conn, err := net.DialUDP(network, localAddr, remoteAddr) 42 if err != nil { 43 return nil, gerror.Wrapf( 44 err, 45 `net.DialUDP failed for network "%s", local "%s", remote "%s"`, 46 network, localAddr.String(), remoteAddr.String(), 47 ) 48 } 49 return conn, nil 50 } 51 52 // Send writes data to `address` using UDP connection and then closes the connection. 53 // Note that it is used for short connection usage. 54 func Send(address string, data []byte, retry ...Retry) error { 55 conn, err := NewConn(address) 56 if err != nil { 57 return err 58 } 59 defer conn.Close() 60 return conn.Send(data, retry...) 61 } 62 63 // SendRecv writes data to `address` using UDP connection, reads response and then closes the connection. 64 // Note that it is used for short connection usage. 65 func SendRecv(address string, data []byte, receive int, retry ...Retry) ([]byte, error) { 66 conn, err := NewConn(address) 67 if err != nil { 68 return nil, err 69 } 70 defer conn.Close() 71 return conn.SendRecv(data, receive, retry...) 72 } 73 74 // MustGetFreePort performs as GetFreePort, but it panics if any error occurs. 75 func MustGetFreePort() (port int) { 76 port, err := GetFreePort() 77 if err != nil { 78 panic(err) 79 } 80 return port 81 } 82 83 // GetFreePort retrieves and returns a port that is free. 84 func GetFreePort() (port int, err error) { 85 var ( 86 network = `udp` 87 address = `:0` 88 ) 89 resolvedAddr, err := net.ResolveUDPAddr(network, address) 90 if err != nil { 91 return 0, gerror.Wrapf( 92 err, 93 `net.ResolveUDPAddr failed for network "%s", address "%s"`, 94 network, address, 95 ) 96 } 97 l, err := net.ListenUDP(network, resolvedAddr) 98 if err != nil { 99 return 0, gerror.Wrapf( 100 err, 101 `net.ListenUDP failed for network "%s", address "%s"`, 102 network, resolvedAddr.String(), 103 ) 104 } 105 port = l.LocalAddr().(*net.UDPAddr).Port 106 _ = l.Close() 107 return 108 } 109 110 // GetFreePorts retrieves and returns specified number of ports that are free. 111 func GetFreePorts(count int) (ports []int, err error) { 112 var ( 113 network = `udp` 114 address = `:0` 115 ) 116 for i := 0; i < count; i++ { 117 resolvedAddr, err := net.ResolveUDPAddr(network, address) 118 if err != nil { 119 return nil, gerror.Wrapf( 120 err, 121 `net.ResolveUDPAddr failed for network "%s", address "%s"`, 122 network, address, 123 ) 124 } 125 l, err := net.ListenUDP(network, resolvedAddr) 126 if err != nil { 127 return nil, gerror.Wrapf( 128 err, 129 `net.ListenUDP failed for network "%s", address "%s"`, 130 network, resolvedAddr.String(), 131 ) 132 } 133 ports = append(ports, l.LocalAddr().(*net.UDPAddr).Port) 134 _ = l.Close() 135 } 136 return ports, nil 137 }