2017-04-21 7 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

あなたはnet.Connからの読み取りにbufio.Readerを使用する必要がある、とUDPの場合ではありません接続すると、問題が発生する可能性があります。

UDPはストリームベースではないため、常に個々のデータグラムを読み取る必要があります。最良のケースでは、bufio.Readerはデータを1回だけバッファリングしています。最悪の場合、バッファーはいっぱいになり、部分的な読み取りとデータの損失が発生します。また、複数のデータグラムがバッファリングされると、追加のフレーミングが含まれていない限り、メッセージを区別することができなくなります。

ちょうどあなたの[]bytenet.Connから直接読み取る:

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