为了账号安全,请及时绑定邮箱和手机立即绑定

io.Copy 在 goroutine 中防止阻塞

io.Copy 在 goroutine 中防止阻塞

Go
繁星淼淼 2022-06-13 15:16:06
我正在读《黑帽围棋》这本书。我遇到了一个简单的 TCP 代理示例。它基本上只是转发请求并发回回复。代理代码的要点如下所示(已修改):func handle(src net.Conn) {    dst, err := net.Dial("tcp", "example.com:80")    if err != nil {        log.Fatalln("Unable to connect to remote")    }    defer dst.Close()    // Run in goroutine to prevent io.Copy from blocking    go func() {        if _, err := io.Copy(dst, src); err != nil {            log.Fatalln("Something wrong src -> dst")        }    }()    if _, err := io.Copy(src, dst); err != nil {        log.Fatalln("Something wrong dst -> src")    }}我不明白的部分是注释“在 goroutine 中运行以防止 io.Copy 阻塞”。我已经在有和没有将它包装在 goroutine 中的情况下运行它,它只适用于 goroutine,但我不明白为什么。我们不能io.Copy为请求运行一个阻塞,然后为响应运行另一个阻塞吗?我想我很难理解如果第一个io.Copy在 goroutine 中运行,我们如何保证排序。
查看完整描述

2 回答

?
Helenr

TA贡献1780条经验 获得超4个赞

当您处理 TCP 流时,您必须处理双向的流量,从 src 到 dest 和从 dest 到 src。您可以通过两次复制操作来做到这一点。但是,复制将阻塞,直到它收到错误或 EOF(即套接字关闭),因此您必须将这些复制操作中的至少一个放到 goroutine 中。它的写入方式,一个复制操作将从一个套接字读取并写入另一个,另一个复制操作将执行相反的操作,直到出现错误或 EOF。当收到错误或 EOF 时,两个复制操作都将停止。



查看完整回答
反对 回复 2022-06-13
?
杨魅力

TA贡献1811条经验 获得超6个赞

io.Copy 函数在 reader 或 writer 返回错误(包括 io.EOF)后返回。如果 io.Copy 调用未在 Go 例程中运行,则在将任何数据从 dst 复制到 src 之前,所有数据都会从 src 复制到 dst。



查看完整回答
反对 回复 2022-06-13
  • 2 回答
  • 0 关注
  • 279 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信