為每個client fd開兩個goroutine,一個recv,一個send。同時還有加2個channel,一個用于recv routine向邏輯主線程傳送收到的數(shù)據(jù),一個用于邏輯主線程向send goroutine傳送待發(fā)送的數(shù)據(jù),是這樣的么?
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、微信平臺小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了信陽免費(fèi)建站歡迎大家使用!
實際上需要 3 個 goroutine,一個 read,一個 send,還有一個 handle。
read goroutine 讀,然后寫入 recevice chan。
write goroutine 把 send chan 的東西寫。
handle goroutine 是 conn 的主要處理邏輯,負(fù)責(zé)把 recevice chan 的東西讀出來 call 業(yè)務(wù)邏輯。
業(yè)務(wù)邏輯中要寫數(shù)據(jù)就直接寫入 send chan。
這樣就可以保證,業(yè)務(wù)邏輯的讀寫都是在 handle goroutine 上處理,而避免 race 產(chǎn)生。
如果需要定時任務(wù)(比如心跳),就在 handle goroutine 上加上一個 timer.C;
如果需要 goroutine 下發(fā)任務(wù),在 handle goroutine 增加一個 task chan,hanlde 收到 task 后處理業(yè)務(wù);
如果需要輸出結(jié)果,那就增加 result chan,業(yè)務(wù)邏輯把數(shù)據(jù)輸出即可。
----------------------------
還有,如果我開2個goroutine的話,client斷開連接了,假設(shè)recv goroutine先發(fā)生err并且close(fd),那在send goroutine中該如何處理呢?有可能不應(yīng)該這樣處理,那應(yīng)該怎么處理呢?
如果 net.Conn Close() 了,不論 Read() 阻塞還是 Write() 阻塞都會立即收到 err 返回。
一般來說,Write() 是不可能主動知道連接斷開的,除非是 SetDeadline() 猜測對方斷掉了,指定時間內(nèi)沒有寫成功就認(rèn)為是斷開。Read() 是可以主動收到對方發(fā)來的斷開(TCP FIN),但也沒辦法知道異常的斷開(當(dāng)然也可以設(shè)置超時)。
無論是誰,是確實收到 FIN 還是 Deadline 猜測斷開,只要 Close() 大家就知道連接斷開了。
handle goroutine 還有一個用處就是:你的程序主動結(jié)束的時候,能正確的 close conn,讓對方知道你是真的斷開了,而不用去猜。
socket代理又分為socket4和sockt5代理,其中socket4只能支持TCP協(xié)議,而socket5則同時支持TCP協(xié)議和UDP協(xié)議。
阻塞socket和非阻塞socket的區(qū)別: 1、讀操作 對于阻塞的socket,當(dāng)socket的接收緩沖區(qū)中沒有數(shù)據(jù)時,read調(diào)用會一直阻塞住,直到有數(shù)據(jù)到來才返回。當(dāng)socket緩沖區(qū)中的數(shù)據(jù)量小于期望讀取的數(shù)據(jù)量時,返回實際讀取的字節(jié)數(shù)。