socket代理又分為socket4和sockt5代理,其中socket4只能支持TCP協(xié)議,而socket5則同時(shí)支持TCP協(xié)議和UDP協(xié)議。
創(chuàng)新互聯(lián)建站主要從事成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)瓊結(jié),十多年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專(zhuān)業(yè),歡迎來(lái)電咨詢建站服務(wù):028-86922220
Socket通信的原理還是比較簡(jiǎn)單的, 它大致分為以下幾個(gè)步驟。 服務(wù)器端的步驟如下。 (1)建立服務(wù)器端的Socket,開(kāi)始偵聽(tīng)整個(gè)網(wǎng)絡(luò)中的連接請(qǐng)求。 (2)當(dāng)檢測(cè)到來(lái)自客戶端的連接請(qǐng)求時(shí),向客戶端發(fā)送收到連接請(qǐng)求的信息,并建立與客戶端之間的...
為每個(gè)client fd開(kāi)兩個(gè)goroutine,一個(gè)recv,一個(gè)send。同時(shí)還有加2個(gè)channel,一個(gè)用于recv routine向邏輯主線程傳送收到的數(shù)據(jù),一個(gè)用于邏輯主線程向send goroutine傳送待發(fā)送的數(shù)據(jù),是這樣的么?
實(shí)際上需要 3 個(gè) goroutine,一個(gè) read,一個(gè) send,還有一個(gè) handle。
read goroutine 讀,然后寫(xiě)入 recevice chan。
write goroutine 把 send chan 的東西寫(xiě)。
handle goroutine 是 conn 的主要處理邏輯,負(fù)責(zé)把 recevice chan 的東西讀出來(lái) call 業(yè)務(wù)邏輯。
業(yè)務(wù)邏輯中要寫(xiě)數(shù)據(jù)就直接寫(xiě)入 send chan。
這樣就可以保證,業(yè)務(wù)邏輯的讀寫(xiě)都是在 handle goroutine 上處理,而避免 race 產(chǎn)生。
如果需要定時(shí)任務(wù)(比如心跳),就在 handle goroutine 上加上一個(gè) timer.C;
如果需要 goroutine 下發(fā)任務(wù),在 handle goroutine 增加一個(gè) task chan,hanlde 收到 task 后處理業(yè)務(wù);
如果需要輸出結(jié)果,那就增加 result chan,業(yè)務(wù)邏輯把數(shù)據(jù)輸出即可。
----------------------------
還有,如果我開(kāi)2個(gè)goroutine的話,client斷開(kāi)連接了,假設(shè)recv goroutine先發(fā)生err并且close(fd),那在send goroutine中該如何處理呢?有可能不應(yīng)該這樣處理,那應(yīng)該怎么處理呢?
如果 net.Conn Close() 了,不論 Read() 阻塞還是 Write() 阻塞都會(huì)立即收到 err 返回。
一般來(lái)說(shuō),Write() 是不可能主動(dòng)知道連接斷開(kāi)的,除非是 SetDeadline() 猜測(cè)對(duì)方斷掉了,指定時(shí)間內(nèi)沒(méi)有寫(xiě)成功就認(rèn)為是斷開(kāi)。Read() 是可以主動(dòng)收到對(duì)方發(fā)來(lái)的斷開(kāi)(TCP FIN),但也沒(méi)辦法知道異常的斷開(kāi)(當(dāng)然也可以設(shè)置超時(shí))。
無(wú)論是誰(shuí),是確實(shí)收到 FIN 還是 Deadline 猜測(cè)斷開(kāi),只要 Close() 大家就知道連接斷開(kāi)了。
handle goroutine 還有一個(gè)用處就是:你的程序主動(dòng)結(jié)束的時(shí)候,能正確的 close conn,讓對(duì)方知道你是真的斷開(kāi)了,而不用去猜。