2 回答
TA贡献1793条经验 获得超6个赞
你不能close多次调用一个通道,没有理由调用copyfor 循环,因为它只能运行一次,而且你正在向错误的方向复制,写入标准输入并从标准输出读取。
简单地询问如何退出 2 个 goroutines 很简单,但这不是您在这里需要做的唯一事情。由于io.Copy是阻塞,您不需要额外的同步来确定调用何时完成。这使您可以显着简化代码,从而更容易推理。
func interact(c net.Conn) {
go func() {
// You want to close this outside the goroutine if you
// expect to send data back over a half-closed connection
defer c.Close()
// Optionally close stdout here if you need to signal the
// end of the stream in a pipeline.
defer os.Stdout.Close()
_, err := io.Copy(os.Stdout, c)
if err != nil {
//
}
}()
_, err := io.Copy(c, os.Stdin)
if err != nil {
//
}
}
另请注意,您可能无法跳出io.Copyfrom stdin,因此您不能指望函数interact返回。在函数体中手动执行io.Copy并检查每个循环的半关闭连接可能是个好主意,这样您就可以更快地退出并确保完全关闭net.Conn.
TA贡献1876条经验 获得超5个赞
也可以是这样的
func scanReader(quit chan int, r io.Reader) chan string {
line := make(chan string)
go func(quit chan int) {
defer close(line)
scan := bufio.NewScanner(r)
for scan.Scan() {
select {
case <- quit:
return
default:
s := scan.Text()
line <- s
}
}
}(quit)
return line
}
stdIn := scanReader(quit, os.Stdin)
conIn := scanReader(quit, c)
for {
select {
case <-quit:
return
case l <- stdIn:
_, e := fmt.Fprintf(c, l)
if e != nil {
quit <- 1
return
}
case l <- conIn:
fmt.Println(l)
}
}
- 2 回答
- 0 关注
- 124 浏览
添加回答
举报