使用 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端监听
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端监听
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
client