美文网首页
GO UDP编程

GO UDP编程

作者: 舍是境界 | 来源:发表于2022-01-14 07:11 被阅读0次

    本文介绍golang下的UDP编程,并给到相关示例代码:

    用户数据报协议(User Datagram Protocol,缩写为UDP),又称用户数据报文协议,是一个简单的面向数据报(package-oriented)的传输层协议,正式规范为RFC 768。

    UDP只提供数据的不可靠传递,它一旦把应用程序发给网络层的数据发送出去,就不保留数据备份(所以UDP有时候也被认为是不可靠的数据报协议)。

    UDP在IP数据报的头部仅仅加入了复用和数据校验。

    由于缺乏可靠性且属于非连接导向协议,UDP应用一般必须允许一定量的丢包、出错和复制粘贴。

    注意事项

    1. 在接收udp包时,如果接收包时给定的buffer太小的话,就要自己解决粘包问题。
    2. udp包的发送和接收不保证一定成功,不保证按正确顺序抵达。
    3. 简单实现方式可以改为一次接收保证数据完全得到,超限的忽略

    示例代码:

    package net
    
    import (
        "bufio"
        "bytes"
        "fmt"
        "net"
        "os"
        "strconv"
        "strings"
    )
    
    const (
        SERVER_IP           = "127.0.0.1"
        SERVER_PORT         = 10006
        SERVER_RECV_MAX_LEN = 2048 //2k
    )
    
    func StartUdpServer() {
        address := SERVER_IP + ":" + strconv.Itoa(SERVER_PORT)
        addr, err := net.ResolveUDPAddr("udp", address)
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
    
        conn, err := net.ListenUDP("udp", addr)
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
    
        defer conn.Close()
    
        for {
            data := make([]byte, SERVER_RECV_MAX_LEN)
            _, rAddr, err := conn.ReadFromUDP(data)
            if err != nil {
                fmt.Println(err)
                continue
            }
            data = bytes.Trim(data, "\x00")
    
            strData := string(data)
            fmt.Println("Received", strData)
    
            sendData := "received:" + strData
            _, err = conn.WriteToUDP([]byte(sendData), rAddr)
            if err != nil {
                fmt.Println(err)
                continue
            }
    
            fmt.Println("Received", sendData)
        }
    }
    
    func StartUdpClient(){
        serverAddr := SERVER_IP + ":" + strconv.Itoa(SERVER_PORT)
        conn, err := net.Dial("udp", serverAddr)
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
    
        defer conn.Close()
    
        input := bufio.NewScanner(os.Stdin)
        for input.Scan() {
            line := input.Text()
            lineLen := len(line)
    
            n := 0
            for written := 0; written < lineLen; written += n {
                var toWrite string
                if lineLen - written > SERVER_RECV_MAX_LEN {
                    toWrite = line[written: written +SERVER_RECV_MAX_LEN]
                }else {
                    toWrite = line[written:]
                }
    
                n, err = conn.Write([]byte(toWrite))
                if err != nil {
                    fmt.Println(err)
                    os.Exit(1)
                }
    
                fmt.Println("client Write: " + toWrite)
    
                msg := make([]byte, SERVER_RECV_MAX_LEN)
                n, err = conn.Read(msg)
                if err != nil {
                    fmt.Println(err)
                    os.Exit(1)
                }
    
                msg = bytes.Trim(msg, "\x00")
    
                fmt.Println("client received: " + strings.TrimSpace(string(msg)))
    
            }
        }
    }
    

    输出结果:

    #客户端:
    11
    client Write: 11
    client received: received:11
    shimahahahhahaha
    client Write: shimahahahhahaha
    client received: received:shimahahahhahaha
    
    #服务端
    Received 11
    Received received:11
    Received shimahahahhahaha
    Received received:shimahahahhahaha
    

    小结

    本文通过代码简单使用了golang的udp编程,希望对你能有所帮助

    相关文章

      网友评论

          本文标题:GO UDP编程

          本文链接:https://www.haomeiwen.com/subject/ttsucrtx.html