// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package netimport ()// BUG(mikio): On Plan 9, the ReadMsgUDP and// WriteMsgUDP methods of UDPConn are not implemented.// BUG(mikio): On Windows, the File method of UDPConn is not// implemented.// BUG(mikio): On JS, methods and functions related to UDPConn are not// implemented.// UDPAddr represents the address of a UDP end point.typeUDPAddrstruct { IP IP Port int Zone string// IPv6 scoped addressing zone}// Network returns the address's network name, "udp".func ( *UDPAddr) () string { return"udp" }func ( *UDPAddr) () string {if == nil {return"<nil>" } := ipEmptyString(.IP)if .Zone != "" {returnJoinHostPort(+"%"+.Zone, itoa(.Port)) }returnJoinHostPort(, itoa(.Port))}func ( *UDPAddr) () bool {if == nil || .IP == nil {returntrue }return .IP.IsUnspecified()}func ( *UDPAddr) () Addr {if == nil {returnnil }return}// ResolveUDPAddr returns an address of UDP end point.//// The network must be a UDP network name.//// If the host in the address parameter is not a literal IP address or// the port is not a literal port number, ResolveUDPAddr resolves the// address to an address of UDP end point.// Otherwise, it parses the address as a pair of literal IP address// and port number.// The address parameter can use a host name, but this is not// recommended, because it will return at most one of the host name's// IP addresses.//// See func Dial for a description of the network and address// parameters.func (, string) (*UDPAddr, error) {switch {case"udp", "udp4", "udp6":case"": // a hint wildcard for Go 1.0 undocumented behavior = "udp"default:returnnil, UnknownNetworkError() } , := DefaultResolver.internetAddrList(context.Background(), , )if != nil {returnnil, }return .forResolve(, ).(*UDPAddr), nil}// UDPConn is the implementation of the Conn and PacketConn interfaces// for UDP network connections.typeUDPConnstruct {conn}// SyscallConn returns a raw network connection.// This implements the syscall.Conn interface.func ( *UDPConn) () (syscall.RawConn, error) {if !.ok() {returnnil, syscall.EINVAL }returnnewRawConn(.fd)}// ReadFromUDP acts like ReadFrom but returns a UDPAddr.func ( *UDPConn) ( []byte) (int, *UDPAddr, error) {if !.ok() {return0, nil, syscall.EINVAL } , , := .readFrom()if != nil { = &OpError{Op: "read", Net: .fd.net, Source: .fd.laddr, Addr: .fd.raddr, Err: } }return , , }// ReadFrom implements the PacketConn ReadFrom method.func ( *UDPConn) ( []byte) (int, Addr, error) {if !.ok() {return0, nil, syscall.EINVAL } , , := .readFrom()if != nil { = &OpError{Op: "read", Net: .fd.net, Source: .fd.laddr, Addr: .fd.raddr, Err: } }if == nil {return , nil, }return , , }// ReadMsgUDP reads a message from c, copying the payload into b and// the associated out-of-band data into oob. It returns the number of// bytes copied into b, the number of bytes copied into oob, the flags// that were set on the message and the source address of the message.//// The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be// used to manipulate IP-level socket options in oob.func ( *UDPConn) (, []byte) (, , int, *UDPAddr, error) {if !.ok() {return0, 0, 0, nil, syscall.EINVAL } , , , , = .readMsg(, )if != nil { = &OpError{Op: "read", Net: .fd.net, Source: .fd.laddr, Addr: .fd.raddr, Err: } }return}// WriteToUDP acts like WriteTo but takes a UDPAddr.func ( *UDPConn) ( []byte, *UDPAddr) (int, error) {if !.ok() {return0, syscall.EINVAL } , := .writeTo(, )if != nil { = &OpError{Op: "write", Net: .fd.net, Source: .fd.laddr, Addr: .opAddr(), Err: } }return , }// WriteTo implements the PacketConn WriteTo method.func ( *UDPConn) ( []byte, Addr) (int, error) {if !.ok() {return0, syscall.EINVAL } , := .(*UDPAddr)if ! {return0, &OpError{Op: "write", Net: .fd.net, Source: .fd.laddr, Addr: , Err: syscall.EINVAL} } , := .writeTo(, )if != nil { = &OpError{Op: "write", Net: .fd.net, Source: .fd.laddr, Addr: .opAddr(), Err: } }return , }// WriteMsgUDP writes a message to addr via c if c isn't connected, or// to c's remote address if c is connected (in which case addr must be// nil). The payload is copied from b and the associated out-of-band// data is copied from oob. It returns the number of payload and// out-of-band bytes written.//// The packages golang.org/x/net/ipv4 and golang.org/x/net/ipv6 can be// used to manipulate IP-level socket options in oob.func ( *UDPConn) (, []byte, *UDPAddr) (, int, error) {if !.ok() {return0, 0, syscall.EINVAL } , , = .writeMsg(, , )if != nil { = &OpError{Op: "write", Net: .fd.net, Source: .fd.laddr, Addr: .opAddr(), Err: } }return}func ( *netFD) *UDPConn { return &UDPConn{conn{}} }// DialUDP acts like Dial for UDP networks.//// The network must be a UDP network name; see func Dial for details.//// If laddr is nil, a local address is automatically chosen.// If the IP field of raddr is nil or an unspecified IP address, the// local system is assumed.func ( string, , *UDPAddr) (*UDPConn, error) {switch {case"udp", "udp4", "udp6":default:returnnil, &OpError{Op: "dial", Net: , Source: .opAddr(), Addr: .opAddr(), Err: UnknownNetworkError()} }if == nil {returnnil, &OpError{Op: "dial", Net: , Source: .opAddr(), Addr: nil, Err: errMissingAddress} } := &sysDialer{network: , address: .String()} , := .dialUDP(context.Background(), , )if != nil {returnnil, &OpError{Op: "dial", Net: , Source: .opAddr(), Addr: .opAddr(), Err: } }return , nil}// ListenUDP acts like ListenPacket for UDP networks.//// The network must be a UDP network name; see func Dial for details.//// If the IP field of laddr is nil or an unspecified IP address,// ListenUDP listens on all available IP addresses of the local system// except multicast IP addresses.// If the Port field of laddr is 0, a port number is automatically// chosen.func ( string, *UDPAddr) (*UDPConn, error) {switch {case"udp", "udp4", "udp6":default:returnnil, &OpError{Op: "listen", Net: , Source: nil, Addr: .opAddr(), Err: UnknownNetworkError()} }if == nil { = &UDPAddr{} } := &sysListener{network: , address: .String()} , := .listenUDP(context.Background(), )if != nil {returnnil, &OpError{Op: "listen", Net: , Source: nil, Addr: .opAddr(), Err: } }return , nil}// ListenMulticastUDP acts like ListenPacket for UDP networks but// takes a group address on a specific network interface.//// The network must be a UDP network name; see func Dial for details.//// ListenMulticastUDP listens on all available IP addresses of the// local system including the group, multicast IP address.// If ifi is nil, ListenMulticastUDP uses the system-assigned// multicast interface, although this is not recommended because the// assignment depends on platforms and sometimes it might require// routing configuration.// If the Port field of gaddr is 0, a port number is automatically// chosen.//// ListenMulticastUDP is just for convenience of simple, small// applications. There are golang.org/x/net/ipv4 and// golang.org/x/net/ipv6 packages for general purpose uses.//// Note that ListenMulticastUDP will set the IP_MULTICAST_LOOP socket option// to 0 under IPPROTO_IP, to disable loopback of multicast packets.func ( string, *Interface, *UDPAddr) (*UDPConn, error) {switch {case"udp", "udp4", "udp6":default:returnnil, &OpError{Op: "listen", Net: , Source: nil, Addr: .opAddr(), Err: UnknownNetworkError()} }if == nil || .IP == nil {returnnil, &OpError{Op: "listen", Net: , Source: nil, Addr: .opAddr(), Err: errMissingAddress} } := &sysListener{network: , address: .String()} , := .listenMulticastUDP(context.Background(), , )if != nil {returnnil, &OpError{Op: "listen", Net: , Source: nil, Addr: .opAddr(), Err: } }return , nil}