我正在讀《黑帽圍棋》這本書。我遇到了一個簡單的 TCP 代理示例。它基本上只是轉(zhuǎn)發(fā)請求并發(fā)回回復(fù)。代理代碼的要點如下所示(已修改):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 阻塞”。我已經(jīng)在有和沒有將它包裝在 goroutine 中的情況下運行它,它只適用于 goroutine,但我不明白為什么。我們不能io.Copy為請求運行一個阻塞,然后為響應(yīng)運行另一個阻塞嗎?我想我很難理解如果第一個io.Copy在 goroutine 中運行,我們?nèi)绾伪WC排序。
2 回答

Helenr
TA貢獻1780條經(jīng)驗 獲得超4個贊
當(dāng)您處理 TCP 流時,您必須處理雙向的流量,從 src 到 dest 和從 dest 到 src。您可以通過兩次復(fù)制操作來做到這一點。但是,復(fù)制將阻塞,直到它收到錯誤或 EOF(即套接字關(guān)閉),因此您必須將這些復(fù)制操作中的至少一個放到 goroutine 中。它的寫入方式,一個復(fù)制操作將從一個套接字讀取并寫入另一個,另一個復(fù)制操作將執(zhí)行相反的操作,直到出現(xiàn)錯誤或 EOF。當(dāng)收到錯誤或 EOF 時,兩個復(fù)制操作都將停止。

楊魅力
TA貢獻1811條經(jīng)驗 獲得超6個贊
io.Copy 函數(shù)在 reader 或 writer 返回錯誤(包括 io.EOF)后返回。如果 io.Copy 調(diào)用未在 Go 例程中運行,則在將任何數(shù)據(jù)從 dst 復(fù)制到 src 之前,所有數(shù)據(jù)都會從 src 復(fù)制到 dst。
- 2 回答
- 0 關(guān)注
- 324 瀏覽
添加回答
舉報
0/150
提交
取消