【发布时间】:2017-04-21 02:51:56
【问题描述】:
相信我要么误解了 go 例程的工作原理,要么误解了缓冲阅读器的工作原理,或者两者兼而有之。
期望异步执行 goroutine(带有 for 循环的缓冲读取器读取缓冲区,等待来自服务器的消息)
尝试METHOD A在客户端拨打服务器之前调用go xyz();所以xyz() 创建缓冲区并开始在后台读取。然后,客户端拨打服务器;服务器发回消息;客户端正在读取缓冲区,因此它获取消息并打印到控制台
实际发生的情况 客户端将消息发送到服务器,但在读取可能来自服务器的回复时不会在缓冲区中获取任何内容;所以它同时运行,因为我知道 for 循环没有停止,但它让下一行代码执行(客户端向服务器发送消息)。
但是当 METHOD B 我不是同时调用xyz() 并且在客户端拨打服务器之后,所有事情都按预期工作。客户端从服务器获取消息并打印到控制台。
方法A,我们有顺序:
//////////// 步骤 1 和 2 在由 go xyz() 调用的 goroutine 中
- 创建缓冲阅读器
- for循环——从服务器读取消息缓冲区——打印出来
-
客户端拨打服务器
go xyz(conn, p)fmt.Fprintf(conn, "Give me a hash to work on ...")
方法B,我们有顺序:
//////////// 步骤 2 和 3 在由 xyz() 调用的 goroutine 中
- 客户端拨打服务器
- 创建缓冲阅读器
-
for循环——从服务器读取消息的缓冲区——打印出来
fmt.Fprintf(conn, "Give me a hash to work on ...")xyz(conn, p)
client.go
package main
import (
"fmt"
"net"
"bufio"
)
func xyz(conn net.Conn, p []byte) {
rd := bufio.NewReader(conn)
for {
_, err := rd.Read(p)
if err == nil {
fmt.Printf("SERVER : %s\n", p)
} else {
fmt.Printf("Some error %v\n", err)
}
}
}
func main() {
p := make([]byte, 2048)
conn, err := net.Dial("udp", "127.0.0.1:1234")
if err != nil {
fmt.Printf("Some error %v", err)
return
}
go xyz(conn, p)
fmt.Fprintf(conn, "Give me a hash to work on ...")
}
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)
}
}
【问题讨论】:
标签: go concurrency udp bufferedreader