Featured image of post Golang 实现一个基础UDP通信服务

Golang 实现一个基础UDP通信服务

使用 golang 实现一个 UDP 通信服务.

net 包

这里主要用到 golang net 包.

net.ResolveUDPAddr

方法

ResolveTCPAddr 将 addr 作为 TCP 地址解析并返回。参数 addr 格式为"host:port"或"[ipv6-host%zone]:port",解析得到网络名和端口名;net 必须是"udp"、“udp4"或"udp6”。
IPv6 地址字面值/名称必须用方括号包起来,如"[::1]:80"、"[ipv6-host]:http"或"[ipv6-host%zone]:80"。

net.ListenUDP 方法

ListenUDP 创建一个接收目的地是本地地址 laddr 的 UDP 数据包的网络连接。net 必须是"udp"、“udp4”、“udp6”;如果 laddr 端口为 0,函数将选择一个当前可用的端口,可以用 Listener 的 Addr 方法获得该端口。返回的*UDPConn 的 ReadFrom 和 WriteTo 方法可以用来发送和接收 UDP 数据包(每个包都可获得来源地址或设置目标地址)。

server 端监听

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package main

import (
	"net"
	"log"
	"fmt"
)

const (
	netWork = "udp"
	post = ":8080"
	msgLength = 1024
)

func handler(conn *net.UDPConn)  {
	for true  {
		data := make([]byte, msgLength)
		read, remoteAddr, err := conn.ReadFromUDP(data)
		if nil != err {
			fmt.Println("read date ", err)
			continue
		}

		fmt.Println("25", read, remoteAddr)

		fmt.Printf("26 %s\n", string(data))

		sendData := []byte("hi client!")
		_, err = conn.WriteToUDP(sendData, remoteAddr)
		if nil != err {
			log.Fatal("send faild, ", err)
		}
	}
}

func main() {
	addr, err := net.ResolveUDPAddr(netWork, post)
	if nil != err {
		log.Fatal("39 add listen udp server faild ,", err )
	}
	// 添加 监听
	conn, err := net.ListenUDP(netWork, addr)
	if nil != err {
		log.Fatal("44 add listen udp server faild ,", err )
	}
	defer conn.Close()
	fmt.Println("listen udp server ", post)

	handler(conn)
}

client 端监听

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package main

import (
	"net"
	"fmt"
	"time"
	"log"
)

const (
	netWork = "udp4"
	ip = "127.0.0.1"
	port = ":8080"
	msgLength = 1024
)

type client struct {
	isAlive bool
}

var tclient = &client{
	isAlive: true,
}

func handler(conn *net.UDPConn){
	for true  {
		if false == tclient.isAlive {
			tclient.isAlive = true
			fmt.Println("未连接, 10秒后重新连接")
			time.Sleep(10 * time.Second)
			continue
		}
		time.Sleep(2 * time.Second)
		sendData := []byte("client send")
		_, err := conn.Write(sendData)
		if nil != err {
			tclient.isAlive = false
			fmt.Println("send data error ", err)
		}

		data := make([]byte, msgLength)
		read, remoteAddr, err := conn.ReadFromUDP(data)
		if nil != err {
			tclient.isAlive = false
			fmt.Println("recv data error , ", err)
		}

		fmt.Println(read, remoteAddr)
		fmt.Print("%s \n", string(data[:read]), " port:" + remoteAddr.String() )
	}
}

func connect() *net.UDPConn {
	addr, err := net.ResolveUDPAddr(netWork, ip + port)
	if nil != err {
		log.Fatal("Resolve UDP Addr error ", err)
	}
	conn, err := net.DialUDP(netWork, nil, addr)
	if nil != err {
		log.Fatal("Dial UDP error", err)
	}
	return conn
}

func main() {
	conn := connect()
	defer conn.Close()
	handler(conn)
}

运行

同时运行服务端与客户端时可以看到 client 发送 “hi server” 给 server, server 返回 “hi client!” 给 client.

server

Golang实现一个基础UDP通信服务-2023-11-30-14-24-05

client

Golang实现一个基础UDP通信服务-2023-11-30-14-24-11