github.com/wangyougui/gf/v2@v2.6.5/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/wangyougui/gf.
     6  
     7  package gudp
     8  
     9  import (
    10  	"net"
    11  
    12  	"github.com/wangyougui/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  }