一、UDP协议简介
UDP(User Datagram Protocol,用户数据报协议)是Internet传输层协议之一,与TCP(Transmission Control Protocol,传输控制协议)一样工作于 OSI模型的传输层。
和TCP不同的是,UDP不必在发数据前先建立连接,因此传输数据的速度更快,但是可靠性较差。而且处理的数据包大小也有限制,MTU通常为1500字节。
二、Golang对UDP协议的支持
Golang作为一门高效的语言,对网络编程的支持也很强大。它内置了对TCP和UDP协议的支持,并且提供了方便易用的API。
对于UDP协议,Golang提供了两种方式处理数据:
- PacketConn:基于数据包的方式传输UDP数据
- Conn:基于流的方式传输UDP数据
三、PacketConn方式的使用
PacketConn方式是以数据包(Packet)的形式传输UDP数据。它相对于Conn方式更加简单直接,对于简单应用场景非常适合。
1、服务端代码示例
package main
import (
"fmt"
"net"
)
func main() {
// 监听本地的UDP流量
address, err := net.ResolveUDPAddr("udp", "127.0.0.1:9876")
if err != nil {
fmt.Println(err)
}
conn, err := net.ListenUDP("udp", address)
if err != nil {
fmt.Println(err)
}
// 读取数据
buffer := make([]byte, 1024)
_, clientAddress, err := conn.ReadFromUDP(buffer)
if err != nil {
fmt.Println(err)
}
fmt.Printf("Received: %s from %s\n", buffer, clientAddress.String())
// 发送数据
_, err = conn.WriteToUDP([]byte("Hello, Client!"), clientAddress)
if err != nil {
fmt.Println(err)
}
// 关闭连接
err = conn.Close()
if err != nil {
fmt.Println(err)
}
}
2、客户端代码示例
package main
import (
"fmt"
"net"
)
func main() {
// 连接服务器
serverAddress, err := net.ResolveUDPAddr("udp", "127.0.0.1:9876")
if err != nil {
fmt.Println(err)
}
conn, err := net.DialUDP("udp", nil, serverAddress)
if err != nil {
fmt.Println(err)
}
// 发送数据
data := []byte("Hello, Server!")
_, err = conn.Write(data)
if err != nil {
fmt.Println(err)
}
// 接收数据
buffer := make([]byte, 1024)
_, err = conn.Read(buffer)
if err != nil {
fmt.Println(err)
}
fmt.Printf("Received: %s\n", buffer)
// 关闭连接
err = conn.Close()
if err != nil {
fmt.Println(err)
}
}
四、Conn方式的使用
Conn方式是以流的形式传输UDP数据。它相对于PacketConn方式更加灵活,可以处理更复杂的业务场景。
1、服务端代码示例
package main
import (
"fmt"
"net"
)
func main() {
// 监听本地的UDP流量
address, err := net.ResolveUDPAddr("udp", "127.0.0.1:9876")
if err != nil {
fmt.Println(err)
}
conn, err := net.ListenUDP("udp", address)
if err != nil {
fmt.Println(err)
}
for {
// 读取数据
buffer := make([]byte, 1024)
_, clientAddress, err := conn.ReadFromUDP(buffer)
if err != nil {
fmt.Println(err)
}
fmt.Printf("Received: %s from %s\n", buffer, clientAddress.String())
// 发送数据
_, err = conn.WriteToUDP([]byte("Hello, Client!"), clientAddress)
if err != nil {
fmt.Println(err)
}
}
}
2、客户端代码示例
package main
import (
"fmt"
"net"
)
func main() {
// 连接服务器
serverAddress, err := net.ResolveUDPAddr("udp", "127.0.0.1:9876")
if err != nil {
fmt.Println(err)
}
conn, err := net.DialUDP("udp", nil, serverAddress)
if err != nil {
fmt.Println(err)
}
// 发送数据
data := []byte("Hello, Server!")
_, err = conn.Write(data)
if err != nil {
fmt.Println(err)
}
// 接收数据
buffer := make([]byte, 1024)
_, err = conn.Read(buffer)
if err != nil {
fmt.Println(err)
}
fmt.Printf("Received: %s\n", buffer)
}
五、总结
Golang对于UDP协议的支持非常强大,并且使用方便。在实际的项目中,可以根据业务场景选择不同的方式来处理UDP数据。
原创文章,作者:AGWW,如若转载,请注明出处:https://www.506064.com/n/136121.html
微信扫一扫
支付宝扫一扫