Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

UDP

特点

  • 无连接:只知道对端的IP和端口号就可以发送,不需要实现建立连接。
  • 不可靠:没有确认机制, 没有重传机制。如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层返回任何错误信息。
  • 面向数据报: 应用层交给UDP多长的报文, UDP原样发送既不会拆分,也不会合并。如果发送端调用一次sendto, 发送100个字节, 那么接收端也必须调用对应的一次recvfrom, 接收100个 字节,而不能循环调用10次recvfrom, 每次接收10个字节。所以UDP不能够灵活的控制读写数据的次数和数量。
  • UDP存在接收缓冲区,但不存在发送缓冲区。

协议

https://zhuanlan.zhihu.com/p/357080855

服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import (
"fmt"
"net"
)

func main() {
udp, err := net.ListenUDP("udp", &net.UDPAddr{
IP: net.IPv4(0, 0, 0, 0),
Port: 9999,
})
if err != nil {
fmt.Println(err)
return
}
defer udp.Close()
for {
var revfromclient [1024]byte
n, addr, err := udp.ReadFromUDP(revfromclient[:])
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%s client send: %s \n", addr, string(revfromclient[:n]))
udp.WriteTo([]byte("OK\r"), addr)
}
}

客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package main

import (
"bufio"
"fmt"
"net"
"os"
)

func main() {

dial, err := net.Dial("udp", "0.0.0.0:9999")

if err != nil {
fmt.Println("网络错误")
return

}

defer dial.Close()

input := bufio.NewReader(os.Stdin)

for {
s, _ := input.ReadString('\n')
_, err = dial.Write([]byte(s))
if err != nil {
fmt.Println("发送数据失败")
return
}
}

//接收数据
var b [1024]byte

n, err := dial.Read(b[:])

if err != nil {
fmt.Println("接收数据失败")
return
}
fmt.Println("接收的消息:", string(b[:n]))

}

评论