介绍
用户数据报协议(User Datagram Protocol,缩写为UDP),又称用户数据报文协议,是一个简单的面向数据报(package-oriented)的传输层协议,正式规范为RFC 768。
UDP只提供数据的不可靠传递,它一旦把应用程序发给网络层的数据发送出去,就不保留数据备份(所以UDP有时候也被认为是不可靠的数据报协议)。
UDP在IP数据报的头部仅仅加入了复用和数据校验。
由于缺乏可靠性且属于非连接导向协议,UDP应用一般必须允许一定量的丢包、出错和复制粘贴。
注意
1 在接收udp包时,如果接收包时给定的buffer太小的话,就要自己解决粘包问题。
2 udp包的发送和接收不保证一定成功,不保证按正确顺序抵达。
3 如果不允许丢包的情况出现的话,要有重发机制来保证,如:反馈机制确认。
示例
服务端
package main
import (
"fmt"
"net"
"strings"
)
// 读取消息
func handleConnection(udpConn *net.UDPConn) {
// 读取数据
buf := make([]byte, 1024)
len, udpAddr, err := udpConn.ReadFromUDP(buf)
if err != nil{
return
}
logContent := strings.Replace(string(buf),"\n","",1)
fmt.Println("server read len:", len)
fmt.Println("server read data:", logContent)
// 发送数据
len, err = udpConn.WriteToUDP([]byte("ok\r\n"), udpAddr)
if err != nil{
return
}
fmt.Println("server write len:", len,"\n")
}
// udp 服务端
func main() {
/*
network: "udp"、"udp4"或"udp6"
addr: "host:port"或"[ipv6-host%zone]:port"
*/
udpAddr, _ := net.ResolveUDPAddr("udp4", "127.0.0.1:9998")
//监听端口
udpConn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
fmt.Println(err)
}
defer udpConn.Close()
fmt.Println("udp listening ... ")
//udp不需要Accept
for {
handleConnection(udpConn)
}
}
客户端
package main
import (
"fmt"
"net"
"os"
)
func main() {
udpAddr, _ := net.ResolveUDPAddr("udp4", "127.0.0.1:9998")
//连接udpAddr,返回 udpConn
udpConn, err := net.DialUDP("udp", nil, udpAddr)
if err != nil {
fmt.Println(err)
os.Exit(2)
}
fmt.Println("udp dial ok ")
// 发送数据
len, err := udpConn.Write([]byte("上报日志文件:xxxxxx\r\n"))
if err != nil{
return
}
fmt.Println("client write len:", len)
//读取数据
buf := make([]byte, 1024)
len, _ = udpConn.Read(buf)
fmt.Println("client read len:", len)
fmt.Println("client read data:", string(buf))
}