真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語言實(shí)現(xiàn)tcp的簡單介紹

Go 語言自我提升 (三次握手 - 四次揮手 - TCP狀態(tài)圖 - udp - 網(wǎng)絡(luò)文件傳輸)

三次握手:

創(chuàng)新互聯(lián)專注于中大型企業(yè)的做網(wǎng)站、網(wǎng)站建設(shè)和網(wǎng)站改版、網(wǎng)站營銷服務(wù),追求商業(yè)策劃與數(shù)據(jù)分析、創(chuàng)意藝術(shù)與技術(shù)開發(fā)的融合,累計(jì)客戶千余家,服務(wù)滿意度達(dá)97%。幫助廣大客戶順利對接上互聯(lián)網(wǎng)浪潮,準(zhǔn)確優(yōu)選出符合自己需要的互聯(lián)網(wǎng)運(yùn)用,我們將一直專注品牌網(wǎng)站設(shè)計(jì)和互聯(lián)網(wǎng)程序開發(fā),在前進(jìn)的路上,與客戶一起成長!

1. 主動發(fā)起連接請求端(客戶端),發(fā)送 SYN 標(biāo)志位,攜帶數(shù)據(jù)包、包號

2. 被動接收連接請求端(服務(wù)器),接收 SYN,回復(fù) ACK,攜帶應(yīng)答序列號。同時(shí),發(fā)送SYN標(biāo)志位,攜帶數(shù)據(jù)包、包號

3. 主動發(fā)起連接請求端(客戶端),接收SYN 標(biāo)志位,回復(fù) ACK。

被動端(服務(wù)器)接收 ACK —— 標(biāo)志著 三次握手建立完成( Accept()/Dial() 返回 )

四次揮手:

1. 主動請求斷開連接端(客戶端), 發(fā)送 FIN標(biāo)志,攜帶數(shù)據(jù)包

2. 被動接受斷開連接端(服務(wù)器), 發(fā)送 ACK標(biāo)志,攜帶應(yīng)答序列號。 —— 半關(guān)閉完成。

3. 被動接受斷開連接端(服務(wù)器), 發(fā)送 FIN標(biāo)志,攜帶數(shù)據(jù)包

4. 主動請求斷開連接端(客戶端), 發(fā)送 最后一個(gè) ACK標(biāo)志,攜帶應(yīng)答序列號?!?發(fā)送完成,客戶端不會直接退出,等 2MSL時(shí)長。

等 2MSL待目的:確保服務(wù)器 收到最后一個(gè)ACK

滑動窗口:

通知對端本地存儲數(shù)據(jù)的 緩沖區(qū)容量?!?write 函數(shù)在對端 緩沖區(qū)滿時(shí),有可能阻塞。

TCP狀態(tài)轉(zhuǎn)換:

1. 主動發(fā)起連接請求端:

CLOSED —— 發(fā)送SYN —— SYN_SENT(了解) —— 接收ACK、SYN,回發(fā) ACK —— ESTABLISHED (數(shù)據(jù)通信)

2. 主動關(guān)閉連接請求端:

ESTABLISHED —— 發(fā)送FIN —— FIN_WAIT_1 —— 接收ACK —— FIN_WAIT_2 (半關(guān)閉、主動端)

—— 接收FIN、回復(fù)ACK —— TIME_WAIT (主動端) —— 等 2MSL 時(shí)長 —— CLOSED

3. 被動建立連接請求端:

CLOSED —— LISTEN —— 接收SYN、發(fā)送ACK、SYN —— SYN_RCVD —— 接收 ACK —— ESTABLISHED (數(shù)據(jù)通信)

4. 被動斷開連接請求端:

ESTABLISHED —— 接收 FIN、發(fā)送 ACK —— CLOSE_WAIT —— 發(fā)送 FIN —— LAST_ACK —— 接收ACK —— CLOSED

windows下查看TCP狀態(tài)轉(zhuǎn)換:

netstat -an | findstr? 端口號

Linux下查看TCP狀態(tài)轉(zhuǎn)換:

netstat -an | grep? 端口號

TCP和UDP對比:?

TCP: 面向連接的可靠的數(shù)據(jù)包傳遞。 針對不穩(wěn)定的 網(wǎng)絡(luò)層,完全彌補(bǔ)。ACK

UDP:無連接不可靠的報(bào)文傳輸。 針對不穩(wěn)定的 網(wǎng)絡(luò)層,完全不彌補(bǔ)。還原網(wǎng)絡(luò)真實(shí)狀態(tài)。

優(yōu)點(diǎn)???????????????????????????????????????????????????????????? 缺點(diǎn)

TCP: 可靠、順序、穩(wěn)定 ???????????????????????????????????? 系統(tǒng)資源消耗大,程序?qū)崿F(xiàn)繁復(fù)、速度慢

UDP:系統(tǒng)資源消耗小,程序?qū)崿F(xiàn)簡單、速度快 ???????????????????????? 不可靠、無序、不穩(wěn)定

使用場景:

TCP:大文件、可靠數(shù)據(jù)傳輸。 對數(shù)據(jù)的 穩(wěn)定性、準(zhǔn)確性、一致性要求較高的場合。

UDP:應(yīng)用于對數(shù)據(jù)時(shí)效性要求較高的場合。 網(wǎng)絡(luò)直播、電話會議、視頻直播、網(wǎng)絡(luò)游戲。

UDP-CS-Server實(shí)現(xiàn)流程:

1.? 創(chuàng)建 udp地址結(jié)構(gòu) ResolveUDPAddr(“協(xié)議”, “IP:port”) —— udpAddr 本質(zhì) struct{IP、port}

2.? 創(chuàng)建用于 數(shù)據(jù)通信的 socket ListenUDP(“協(xié)議”, udpAddr ) —— udpConn (socket)

3.? 從客戶端讀取數(shù)據(jù),獲取對端的地址 udpConn.ReadFromUDP() —— 返回:n,clientAddr, err

4.? 發(fā)送數(shù)據(jù)包給 客戶端 udpConn.WriteToUDP("數(shù)據(jù)", clientAddr)

UDP-CS-Client實(shí)現(xiàn)流程:

1.? 創(chuàng)建用于通信的 socket。 net.Dial("udp", "服務(wù)器IP:port") —— udpConn (socket)

2.? 以后流程參見 TCP客戶端實(shí)現(xiàn)源碼。

UDPserver默認(rèn)就支持并發(fā)!

------------------------------------

命令行參數(shù): 在main函數(shù)啟動時(shí),向整個(gè)程序傳參。 【重點(diǎn)】

語法: go run xxx.go ? argv1 argv2? argv3? argv4 。。。

xxx.exe:? 第 0 個(gè)參數(shù)。

argv1 :第 1 個(gè)參數(shù)。

argv2 :第 2 個(gè)參數(shù)。

argv3 :第 3 個(gè)參數(shù)。

argv4 :第 4 個(gè)參數(shù)。

使用: list := os.Args? 提取所有命令行參數(shù)。

獲取文件屬性函數(shù):

os.stat(文件訪問絕對路徑) —— fileInfo 接口

fileInfo 包含 兩個(gè)接口。

Name() 獲取文件名。 不帶訪問路徑

Size() 獲取文件大小。

網(wǎng)絡(luò)文件傳輸 —— 發(fā)送端(客戶端)

1.? 獲取命令行參數(shù),得到文件名(帶路徑)filePath list := os.Args

2.? 使用 os.stat() 獲取 文件名(不帶路徑)fileName

3.? 創(chuàng)建 用于數(shù)據(jù)傳輸?shù)?socket? net.Dial("tcp", “服務(wù)器IP+port”) —— conn

4.? 發(fā)送文件名(不帶路徑)? 給接收端, conn.write()

5.? 讀取 接收端回發(fā)“ok”,判斷無誤。封裝函數(shù) sendFile(filePath, conn) 發(fā)送文件內(nèi)容

6.? 實(shí)現(xiàn) sendFile(filePath,? conn)

1) 只讀打開文件 os.Open(filePath)

for {

2) 從文件中讀數(shù)據(jù)? f.Read(buf)

3) 將讀到的數(shù)據(jù)寫到socket中? conn.write(buf[:n])

4)判斷讀取文件的 結(jié)尾。 io.EOF. 跳出循環(huán)

}

網(wǎng)絡(luò)文件傳輸 —— 接收端(服務(wù)器)

1. 創(chuàng)建用于監(jiān)聽的 socket net.Listen() —— listener

2. 借助listener 創(chuàng)建用于 通信的 socket listener.Accpet()? —— conn

3. 讀取 conn.read() 發(fā)送端的 文件名, 保存至本地。

4. 回發(fā) “ok”應(yīng)答 發(fā)送端。

5. 封裝函數(shù),接收文件內(nèi)容 recvFile(文件路徑)

1) f = os.Create(帶有路徑的文件名)

for {

2)從 socket中讀取發(fā)送端發(fā)送的 文件內(nèi)容 。 conn.read(buf)

3)? 將讀到的數(shù)據(jù) 保存至本地文件 f.Write(buf[:n])

4)? 判斷 讀取conn 結(jié)束, 代表文件傳輸完成。 n == 0? break

}

Golang 網(wǎng)絡(luò)編程絲綢之路 - TCP/UDP 地址解析

TL;DR 在使用 Golang 編寫 TCP/UDP socket 的時(shí)候,第一步做的就是地址解析。

該函數(shù)返回的地址包含的信息如下:

TCPAddr 里, IP 既可以是 IPv4 地址,也可以是 IPv6 地址。 Port 就是端口了。 Zone 是 IPv6 本地地址所在的區(qū)域。

從返回結(jié)果看該函數(shù)的參數(shù), network 指 address 的網(wǎng)絡(luò)類型; address 指要解析的地址,會從中解析出我們想要的 IP , Port 和 Zone 。

從源碼中可以看出,參數(shù) network 只能是如下四個(gè)值,否則會得到一個(gè)錯(cuò)誤。

解析過程跟 ResolveTCPAddr 的一樣,不過得到的是 *UDPAddr 。

UDPAddr 包含的信息如下:

【golang】高并發(fā)下TCP常見問題解決方案

首先,看一下TCP握手簡單描繪過程:

其握手過程原理,就不必說了,有很多詳細(xì)文章進(jìn)行敘述,本文只關(guān)注研究重點(diǎn)。

在第三次握手過程中,如果服務(wù)器收到ACK,就會與客戶端建立連接,此時(shí)內(nèi)核會把連接從半連接隊(duì)列移除,然后創(chuàng)建新的連接,并將其添加到全連接隊(duì)列,等待進(jìn)程調(diào)用。

如果服務(wù)器繁忙,來不及調(diào)用連接導(dǎo)致全連接隊(duì)列溢出,服務(wù)器就會放棄當(dāng)前握手連接,發(fā)送RST給客戶端,即connection reset by peer。

在linux平臺上,客戶端在進(jìn)行高并發(fā)TCP連接處理時(shí),最高并發(fā)數(shù)量都要受系統(tǒng)對用戶單一進(jìn)程同時(shí)打開文件數(shù)量的限制(這是因?yàn)橄到y(tǒng)每個(gè)TCP都是SOCKET句柄,每個(gè)soker句柄都是一個(gè)文件),當(dāng)打開連接超過限制,就會出現(xiàn)too many open files。

使用下指令查看最大句柄數(shù)量:

增加句柄解決方案

在 Go 中實(shí)現(xiàn)一個(gè)支持并發(fā)的 TCP 服務(wù)端

TCP 和 UDP 服務(wù)端隨處可見,它們基于 TCP/IP 協(xié)議棧,通過網(wǎng)絡(luò)為客戶端提供服務(wù)。在這篇文章中,我將介紹如何使用 Go 語言開發(fā)一個(gè)用于返回隨機(jī)數(shù)、支持并發(fā)的 TCP 服務(wù)端。對于每一個(gè)來自 TCP 客戶端的連接,它都會啟動一個(gè)新的 goroutine(輕量級線程)來處理相應(yīng)的請求。

你可以在 GitHub 上找到本項(xiàng)目的源碼:concTcp.go。

這個(gè)程序的主要邏輯在 handleConnection 函數(shù)中,具體實(shí)現(xiàn)如下:

在 main 函數(shù)的實(shí)現(xiàn)部分,每當(dāng) TCP 服務(wù)端收到 TCP 客戶端的連接請求,它都會啟動一個(gè)新的 goroutine 來為這個(gè)請求提供服務(wù)。

首先, main 確保程序至少有一個(gè)命令行參數(shù)。注意,現(xiàn)有代碼并沒有檢查這個(gè)參數(shù)是否為有效的 TCP 端口號。不過,如果它是一個(gè)無效的 TCP 端口號, net.Listen 就會調(diào)用失敗,并返回一個(gè)錯(cuò)誤信息,類似下面這樣:

net.Listen 函數(shù)用于告訴 Go 接受網(wǎng)絡(luò)連接,因而承擔(dān)了服務(wù)端的角色。它的返回值類型是 net.Conn ,后者實(shí)現(xiàn)了 io.Reader 和 io.Writer 接口。此外, main 函數(shù)中還調(diào)用了 rand.Seed 函數(shù),用于初始化隨機(jī)數(shù)生成器。最后, for 循環(huán)允許程序一直使用 Accept 函數(shù)來接受 TCP 客戶端的連接請求,并以 goroutine 的方式來運(yùn)行 handleConnection(c) 函數(shù),處理客戶端的后續(xù)請求。

net.Listen 函數(shù)的第一個(gè)參數(shù)定義了使用的網(wǎng)絡(luò)類型,而第二個(gè)參數(shù)定義了服務(wù)端監(jiān)聽的地址和端口號。第一個(gè)參數(shù)的有效值為 tcp 、 tcp4 、 tcp6 、 udp 、 udp4 、 udp6 、 ip 、 ip4 、 ip6 、 Unix (Unix 套接字)、 Unixgram 和 Unixpacket ,其中: tcp4 、 udp4 和 ip4 只接受 IPv4 地址,而 tcp6 、 udp6 和 ip6 只接受 IPv6 地址。

concTCP.go 需要一個(gè)命令行參數(shù),來指定監(jiān)聽的端口號。當(dāng)它開始服務(wù) TCP 客戶端時(shí),你會得到類似下面的輸出:

netstat 的輸出可以確認(rèn) congTCP.go 正在為多個(gè) TCP 客戶端提供服務(wù),并且仍在繼續(xù)監(jiān)聽建立連接的請求:

在上面輸出中,最后一行顯示了有一個(gè)進(jìn)程正在監(jiān)聽 8001 端口,這意味著你可以繼續(xù)連接 TCP 的 8001 端口。第一行和第二行顯示了有一個(gè)已建立的 TCP 網(wǎng)絡(luò)連接,它占用了 8001 和 62556 端口。相似地,第三行和第四行顯示了有另一個(gè)已建立的 TCP 連接,它占用了 8001 和 62554 端口。

下面這張圖片顯示了 concTCP.go 在服務(wù)多個(gè) TCP 客戶端時(shí)的輸出:

類似地,下面這張圖片顯示了兩個(gè) TCP 客戶端的輸出(使用了 nc 工具):

你可以在 維基百科上找到更多關(guān)于 nc (即 netcat )的信息。

現(xiàn)在,你學(xué)會了如何用大約 65 行 Go 代碼來開發(fā)一個(gè)生成隨機(jī)數(shù)、支持并發(fā)的 TCP 服務(wù)端,這真是太棒了!如果你想要讓你的 TCP 服務(wù)端執(zhí)行別的任務(wù),只需要修改 handleConnection 函數(shù)即可。

via:

作者:Mihalis Tsoukalos選題:lkxed譯者:lkxed校對:wxy


網(wǎng)頁題目:go語言實(shí)現(xiàn)tcp的簡單介紹
文章分享:http://weahome.cn/article/doosgcp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部