@(go語言 黑馬)[GO語言]
UDP通信
- 題目:編寫UDP通信的并發(fā)服務(wù)器和客戶端
- 知識點(diǎn):UDP通信
- 邏輯思路(詳細(xì)的步驟在代碼注釋中):
_1. 發(fā)送端 將文件名發(fā)送給 接收端
_2. 接收端 收到文件名后瘫拣,發(fā)送 "ok" 信號給 發(fā)送端
_3. 發(fā)送端 收到 "ok" 信號后,開始傳輸文件內(nèi)容給 接收端
_4. 接收端 接收并保存文件內(nèi)容
服務(wù)器代碼如下:
package main
import "fmt"
func main() {
UdpCommunication()
}
//UDP服務(wù)器
func UdpCommunication() {
//建立UDP客戶端連接奈惑,注意:返回的是服務(wù)器地址述么,不再是listener,不需要監(jiān)聽
clientAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:8002")
if err != nil {
fmt.Println("net.ResolveUDPAddr err:", err)
return
}
fmt.Println("clientAddr",clientAddr)
//建立通信socket颅湘,使用服務(wù)器地址建立
conn, err := net.ListenUDP("udp", clientAddr)
if err != nil {
fmt.Println("net.ListenUDP err:", err)
return
}
defer conn.Close()
buf := make([]byte, 4096)
for {//循環(huán)處理客戶端數(shù)據(jù)
n, UdpAddr, err := conn.ReadFromUDP(buf)//返回值多了一個(gè)客戶端地址
//fmt.Println("UdpAddr:",UdpAddr)//打印客戶端地址
if err != nil {
fmt.Println("conn.ReadFromUDP err:", err)
return
}
fmt.Println("讀到客戶端數(shù)據(jù):", string(buf[:n]))
timeNow := time.Now().String()//現(xiàn)在時(shí)間
conn.WriteToUDP([]byte(timeNow), UdpAddr)
}
}
客戶端代碼如下:
package main
import "fmt"
func main() {
Client()
}
func Client() {
conn, err := net.Dial("udp", "127.0.0.1:8002")//與服務(wù)器建立連接,協(xié)議必須小寫
if err != nil {
fmt.Println("net.Dial err:", err)
return
}
defer conn.Close()//不要忘記關(guān)閉
for {//循環(huán)發(fā)送請求
requst := make([]byte, 4096)
n, err := os.Stdin.Read(requst)
//os.Stdin是標(biāo)準(zhǔn)輸入,返回的是一個(gè)文件指針察署,所以后面直接可以讀取數(shù)據(jù)到緩沖切片中
if err != nil {
fmt.Println("os.Stdin.Read err:", err)
return
}
conn.Write(requst[:n])
buf := make([]byte, 4096)
n, err = conn.Read(buf)
if err != nil {
fmt.Println("conn.Read err:", err)
return
}
fmt.Println("讀到客戶端回發(fā)數(shù)據(jù):", string(buf[:n]))
}
}