【服务端】
func ResolveUDPAddr(network, address string) (*UDPAddr, error)
func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error)
服务端主要通过下面两个函数搭建UDP服务。通过ResolveUDPAddr 获取 ip port
通过ListenUDP 来进行监听,直接返回 *UDPConn类型数据。(面向TCP的 会返回*TCPListener 类型数据)
UDPConn类型 定义如下,本质是 conn
源码在udpsock.go中。
// UDPConn is the implementation of the Conn and PacketConn interfaces
// for UDP network connections.
type UDPConn struct {
conn
}
func ResolveUDPAddr(network, address string) (*UDPAddr, error) {
switch network {
case "udp", "udp4", "udp6":
case "": // a hint wildcard for Go 1.0 undocumented behavior
network = "udp"
default:
return nil, UnknownNetworkError(network)
}
addrs, err := DefaultResolver.internetAddrList(context.Background(), network, address)
if err != nil {
return nil, err
}
return addrs.forResolve(network, address).(*UDPAddr), nil
}
func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error) {
switch network {
case "udp", "udp4", "udp6":
default:
return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
}
if laddr == nil {
laddr = &UDPAddr{}
}
c, err := listenUDP(context.Background(), network, laddr)
if err != nil {
return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
}
return c, nil
}
【服务端代码demo】
package main
import (
"fmt"
"net"
"os"
"time"
)
func main() {
service := ":3000"
myUDPAddr, err := net.ResolveUDPAddr("udp", service)
checkErr(err)
myUDPConn, err := net.ListenUDP("udp", myUDPAddr)
checkErr(err)
for {
dealClient(myUDPConn)
}
}
func dealClient(conn *net.UDPConn) {
var mybuf [512]byte
n, addr, err := conn.ReadFromUDP(mybuf[0:])
if err != nil {
return
}
mytime := time.Now().String()
fmt.Println("news from client: ", string(mybuf[0:n]))
fmt.Println("time @ service: ", mytime)
conn.WriteToUDP([]byte(mytime), addr)
}
func checkErr(err error) {
if err != nil {
fmt.Println("error :", os.Stderr, err.Error())
os.Exit(1)
}
}
【客户端】
func ResolveUDPAddr(network, address string) (*UDPAddr, error)
func DialUDP(network string, laddr, raddr *UDPAddr) (*UDPConn, error)
客户端通过 DialUDP向服务端的发起请求,返回一个*UDPConn类型数据供 写入与读取数据。
// 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 DialUDP(network string, laddr, raddr *UDPAddr) (*UDPConn, error) {
switch network {
case "udp", "udp4", "udp6":
default:
return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
}
if raddr == nil {
return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
}
c, err := dialUDP(context.Background(), network, laddr, raddr)
if err != nil {
return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
}
return c, nil
}
【客户端代码demo】
package main
import (
"fmt"
"net"
"os"
)
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "Usage: %s host:port", os.Args[0])
os.Exit(1)
}
service := os.Args[1]
serAddr, err := net.ResolveUDPAddr("udp", service)
checkErr(err)
myconn, err := net.DialUDP("udp", nil, serAddr)
checkErr(err)
_, err = myconn.Write([]byte("this is from client"))
checkErr(err)
var buf [512]byte
n, err := myconn.Read(buf[0:])
checkErr(err)
fmt.Println(buf[0:n])
fmt.Println(string(buf[0:n]))
os.Exit(0)
}
func checkErr(err error) {
if err != nil {
fmt.Println(os.Stderr, "Fatal err :", err.Error())
os.Exit(1)
}
}
执行结果 略