UDP 客户端

如果您知道怎么开放一个 TCP 客户端,那么由于 UDP 协议的简单性,对于您来说开发一个 UDP 客户端应该更简单。

UDP 和 TCP 最大的不同是 UDP 的不可靠性。这也意味着,UDP 要比 TCP 简单,因为 UDP 不需要保持一个 UDP 连接的状态。

展现这个主题的工具命名为 UDPclient.go,它分成四个代码片段。 UDPclient.go 的第一段如下:

  1. package main
  2. import(
  3. "bufio"
  4. "fmt"
  5. "net"
  6. "os"
  7. "strings"
  8. )

UDPclient.go 的第二段如下:

  1. func main() {
  2. arguments := os.Args
  3. if len(arguments) == 1 {
  4. fmt.Println("Please provide a host:post string")
  5. return
  6. }
  7. CONNECT := arguments[1]
  8. s, err := net.ResolveUDPAddr("udp4", CONNECT)
  9. c, err := net.DialUDP("udp4", nil, s)
  10. if err != nil {
  11. fmt.Println(err)
  12. return
  13. }
  14. fmt.Printf("The UDP server is %s\n", c.RemoteAddr().String())
  15. defer c.Close()

net.ResolveUDPAddr() 函数返回一个由第二个参数定义的 UDP 终点地址。第一个参数(udp4)规定了程序只能支持 IPv4 协议。

net.DialUDP() 函数相当于 net.Dial() 对 UDP 网络。

UDPclient.go 的第三段代码如下:

  1. for {
  2. reader := bufio.NewReader(os.Stdin)
  3. fmt.Print(">> ")
  4. text, _ := reader.ReadString("\n")
  5. data := []byte(text + "\n")
  6. _, err = c.Write(data)
  7. if strings.TrimSpace(string(data)) == "STOP" {
  8. fmt.Println("Exiting UDP client!")
  9. return
  10. }

上面这段代码需要使用者输入一些文本,发送给 UDP 服务器。使用 buio.NewReader(os.Stdin) 从标准输入中读取输入的文本。Write(data) 方法通过 UDP 网络连接发送数据。

剩下的代码如下:

  1. if err != nil {
  2. fmt.Println(err)
  3. return
  4. }
  5. buffer := make([]byte, 1024)
  6. n, _, err := c.ReadFromUDP(buffer)
  7. if err != nil {
  8. fmt.Println(err)
  9. return
  10. }
  11. fmt.Printf("Reply: %s\n", string(buffer[0:n]))
  12. }
  13. }

一旦客户端数据被发送出去后, 您必须等待 UDP 服务器发送的数据,使用 ReadFromUDP() 读取。

执行 UDPclient.go 并使用 netcat(l) 工具作为 UDP 服务器与之交互,将产生如下输出:

  1. $ go run UDPclient.go localhost:8001
  2. The UDP server is 127.0.0.1:8001
  3. >> Hello!
  4. Reply: Hi there!
  5. >> Have to leave - bye!
  6. Reply: OK.
  7. >> STOP
  8. Exiting UDP client!

在 UDP 服务器这边,输出如下:

  1. $ nc -v -u -l 127.0.0.0 8001
  2. Hello!
  3. Hi there!
  4. Have to leave - bye!
  5. OK.
  6. STOP
  7. ^C

因为当 nc(l) 收到输入的STOP 字符串时,没有任何代码能告诉它终止,所以键入 Control + C 去停止它。