缓冲 reader VS listenUDP
Buffered reader VS listenUDP
如果我 "infinitely" 使用 buffered reader
等待来自服务器的消息,这与使用 ListenUDP
不是很相似吗?
但是如果使用ListenUDP
,那么我已经创建了另一个服务器...
"infinitely" 从此 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)
}
}
您不需要使用 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
}
}
如果我 "infinitely" 使用 buffered reader
等待来自服务器的消息,这与使用 ListenUDP
不是很相似吗?
但是如果使用ListenUDP
,那么我已经创建了另一个服务器...
"infinitely" 从此 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)
}
}
您不需要使用 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
}
}