【go语言 socket编程系列】简单UDP协议服务端与客户端的搭建

【服务端】

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)
	}
}

执行结果 略

猜你喜欢

转载自blog.csdn.net/natpan/article/details/82966665