2017-04-21 106 views
0

如果我使用buffered reader等待来自服务器的消息“无限”,这是不是几乎相同,使用ListenUDP缓冲式阅读器VS 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) 
    } 
} 
+0

请使用gofmt! – Flimzy

+1

通过UDP连接使用bufio通常没有任何意义。 UDP基于单独的数据报,试图使用缓冲读取器的目标是什么? – JimB

+0

@JimB ...使用缓冲的阅读器持续等待来自服务器的消息。在任何时候,服务器都可以通过连接发送消息。然后,客户端将根据该消息做事,并将消息发送回服务器。 –

回答

1

你并不需要使用bufio.Readernet.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 
    } 
}