缓冲读卡器VS listenUDP

时间:2017-04-21 04:38:51

标签: go udp buffer bufferedreader

如果我是"无限的"使用buffered reader等待来自服务器的消息,这与使用ListenUDP几乎不一样吗?

但是如果使用ListenUDP,那么我已经创建了另一台服务器......

"无限"是不好的做法?从这个buffered reader收集,或者一般来说是如何与客户完成的?

client.go

package main

import (
    "fmt"
    "time"
    "net"
    "sync"
    "bufio"
)

func xyz(conn net.Conn, p []byte) {
    rd := bufio.NewReader(conn)
    for {
        fmt.Printf("line\n")
        _, err := rd.Read(p)
        if err == nil {
            fmt.Printf("SERVER : %s\n", p)
        } else {
            fmt.Printf("Some error %v\n", err)
        }
    }
}

func main() {
    var wg = &sync.WaitGroup{}
    p :=  make([]byte, 2048)
    conn, err := net.Dial("udp", "127.0.0.1:1234")
    if err != nil {
        fmt.Printf("Some error %v", err)
        return
    }
    wg.Add(1)
    go xyz(conn, p)
    time.Sleep(2 * time.Second);
    fmt.Fprintf(conn, "Give me a hash to work on ...")
    time.Sleep(4 * time.Second)
    wg.Wait()
}

server.go

package main

import (
    "fmt"
    "net"
)

func sendResponse(conn *net.UDPConn, addr *net.UDPAddr, hash string) {
    _,err := conn.WriteToUDP([]byte("Hello, here is the hash  - " + hash), addr)
    if err != nil {
        fmt.Printf("Couldn't send response %v", err)
    }
}

func main() {
    hash := "36";
    p := make([]byte, 2048)
    addr := net.UDPAddr{
        Port: 1234,
        IP: net.ParseIP("127.0.0.1"),
    }
    ser, err := net.ListenUDP("udp", &addr)
    if err != nil {
        fmt.Printf("Some error %v\n", err)
        return
    }
    for {
        _, remoteaddr, err := ser.ReadFromUDP(p)
        fmt.Printf("CLIENT : %v : %s\n", remoteaddr, p)
        if err !=  nil {
            fmt.Printf("Some error  %v", err)
            continue
        }
        go sendResponse(ser, remoteaddr, hash)
    }
}

1 个答案:

答案 0 :(得分:1)

您不需要使用bufio.Reader来读取net.Conn,如果是UDP连接,则只会导致问题。

UDP不是基于流的,因此您始终需要读取每个单独的数据报。在最好的情况下,bufio.Reader只是在一个额外的时间缓冲数据,在最坏的情况下缓冲区接近满,你只得到部分读取,丢失数据。一旦多个数据报被缓冲,您也无法再区分消息,除非它们包含额外的框架。

直接从net.Conn直接阅读[]byte

for {
    n, err := conn.Read(p)
    fmt.Printf("SERVER : %s\n", p[:n])
    if err != nil {
        fmt.Printf("Some error %v\n", err)
        return
    }
}