一、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/zh-hant/n/136121.html
微信掃一掃
支付寶掃一掃