title: 如何選擇TCP長(zhǎng)連接與短連接
author: longzy
time: 2018-11-11
我們?cè)谶M(jìn)行l(wèi)inux網(wǎng)絡(luò)編程時(shí),進(jìn)程間的通信可選的方案有:socket連接瀑梗、管道捏卓、信號(hào)量笤成、共享內(nèi)存、消息隊(duì)列等。而通常最好用的也是最常用的方案是socket連接铝穷。所以今天主要講的是tcp連接敦迄。
這里并不是要講我們?nèi)绾握{(diào)用API去創(chuàng)建一個(gè)tcp的socket連接恋追,而是講我們?cè)谄綍r(shí)的項(xiàng)目中,如何根據(jù)自己的業(yè)務(wù)場(chǎng)景來選擇是建立tcp長(zhǎng)連接還是tcp短連接罚屋。
在這里引入了兩個(gè)概念:長(zhǎng)連接苦囱、短連接。那么長(zhǎng)連接是什么脾猛,短連接又是什么呢撕彤?
長(zhǎng)連接
從生命周期的角度來理解,長(zhǎng)連接的生命周期跟程序的生命周期一樣,程序啟動(dòng)的時(shí)候會(huì)建立好連接羹铅,然后程序結(jié)束后才主動(dòng)關(guān)閉這個(gè)連接蚀狰。注意這里用到了一個(gè)關(guān)鍵詞“主動(dòng)”,也就是長(zhǎng)連接過程中會(huì)有可能因?yàn)槠渌蛩貙?dǎo)致這個(gè)連接被動(dòng)斷開职员,這就要求我們?cè)陂L(zhǎng)連接中用什么方法保證連接還存在麻蹋。(具體的方法后面再講)
短鏈接
同樣從生命周期的角度來考慮,短連接的生命周期跟棧區(qū)的變量一樣焊切,好比某個(gè)函數(shù)里面的局部變量扮授,當(dāng)外面調(diào)用進(jìn)入到某個(gè)函數(shù)內(nèi)部,建立好連接专肪,發(fā)送或接受數(shù)據(jù)刹勃,離開函數(shù)后,該連接就關(guān)閉牵祟。
那么我們?nèi)绾芜x擇長(zhǎng)連接還是短連接呢深夯?別急,在講如何選擇之前诺苹,我們必須的明白tcp建立連接和關(guān)閉連接的這個(gè)過程咕晋,內(nèi)部都做了什么工作。
連接建立
啥也別說收奔,先上個(gè)圖
建立一個(gè)TCP連接時(shí)會(huì)發(fā)生下述情形掌呜。
- server必須準(zhǔn)備好接受外來的連接,這通常是調(diào)用socket坪哄、bind质蕉、和listen等函數(shù)來完成。
- client調(diào)用connect發(fā)起連接翩肌,這時(shí)client TCP發(fā)送一個(gè)SYN模暗,告訴server,client將在待建立的連接中發(fā)送的數(shù)據(jù)的初始序列號(hào)念祭,通常SYN不攜帶數(shù)據(jù)兑宇,其所在的IP數(shù)據(jù)報(bào)只含有一個(gè)IP首部。
- server必須確認(rèn)(ACK)client的SYN粱坤,同時(shí)自己也要發(fā)送一個(gè)SYN包隶糕,它含有server將在同一鏈接中發(fā)送的數(shù)據(jù)的初始序列號(hào)。
- client必須確認(rèn)server的SYN站玄。
這種交換至少需要三個(gè)分組枚驻,所以就是我們常說的三路握手,上圖展示了3個(gè)步驟株旷。上圖中client的初始序列號(hào)為J再登,server的初始序列號(hào)為K,ACK中的確認(rèn)號(hào)是發(fā)送這個(gè)ACK的一端所期待的下一個(gè)序列號(hào)。因?yàn)镾YN占據(jù)一個(gè)字節(jié)的序列號(hào)空間霎冯,所以每一個(gè)SYN的ACK中的確認(rèn)號(hào)就是該SYN的初始序列號(hào)加1铃拇。類似的钞瀑,每一個(gè)FIN的ACK中的確認(rèn)號(hào)為該FIN的序列號(hào)加1.
連接關(guān)閉
同樣先來一個(gè)圖
關(guān)閉一個(gè)TCP連接時(shí)會(huì)發(fā)生以下情況
- 某個(gè)應(yīng)用程序首先調(diào)用close沈撞,我們稱該端執(zhí)行主動(dòng)關(guān)閉,該端的TCP于是發(fā)送一個(gè)FIN雕什,表示數(shù)據(jù)發(fā)送完畢缠俺。
- 接收到這個(gè)FIN的對(duì)端執(zhí)行被動(dòng)關(guān)閉,這個(gè)FIN由TCP確認(rèn)贷岸。它的接收也作為一個(gè)文件結(jié)束符傳遞給接收端應(yīng)用程序壹士,因?yàn)镕IN的接收意味著接收端應(yīng)用程序在相應(yīng)的連接上再無額外數(shù)據(jù)可接收。
- 一段時(shí)間后偿警,接收到這個(gè)文件結(jié)束符的應(yīng)用程序叫調(diào)用close關(guān)閉它的套接字躏救,這導(dǎo)致它的TCP也發(fā)送一個(gè)FIN。
- 接收到這個(gè)最終FIN的原發(fā)送端TCP(主動(dòng)關(guān)閉的那一端)確認(rèn)(ACK)這個(gè)FIN
既然每個(gè)方向都需要一個(gè)FIN和一個(gè)ACK螟蒸,因此通常需要四個(gè)分節(jié)盒使。這就是我們通常所說的四次揮手。注意七嫌,這里我們提到了"通常"少办,是因?yàn)榇嬖谀承┣闆r,步驟1的FIN可能會(huì)隨數(shù)據(jù)一起發(fā)送诵原;另外英妓,步驟2和步驟3都是執(zhí)行被動(dòng)關(guān)閉的那一端發(fā)送的,有可能會(huì)合并成一步绍赛。上圖展示了這些步驟蔓纠。
知道了TCP的連接建立和連接關(guān)閉之后,那么數(shù)據(jù)的發(fā)送就可以用下面這個(gè)圖來解釋了
看了上圖吗蚌,我們是不是對(duì)前面的提到長(zhǎng)連接和短連接更加清楚了腿倚!長(zhǎng)連接對(duì)紅線的部分只做一次,而短連接則整個(gè)過程褪测,都需要全部重做猴誊。
從上面的介紹得知,一個(gè)TCP的連接建立和關(guān)閉侮措,通常是需要七個(gè)分節(jié)的懈叹。所以長(zhǎng)連接和短連接的優(yōu)缺點(diǎn)也就突顯了出來。
連接 | 優(yōu)點(diǎn) | 缺點(diǎn) |
---|---|---|
長(zhǎng)連接 | 傳輸速度快分扎,server可以主動(dòng)發(fā)送數(shù)據(jù)給client | 保持的連接會(huì)占用和多系統(tǒng)資源澄成, 后臺(tái)設(shè)計(jì)相對(duì)要復(fù)雜 |
短連接 | 不需要占用系統(tǒng)的太多的資源使得server可以處理更多client的connect | 發(fā)送小數(shù)據(jù)劃不來,比較耗時(shí)。server無法主動(dòng)發(fā)送數(shù)據(jù)到client |
讀到這里墨状,你是不是已經(jīng)對(duì)如何選擇長(zhǎng)連接還是短連接已經(jīng)有自己的想法了呢卫漫?
總結(jié)
- 如果業(yè)務(wù)來往比較頻繁,則選擇長(zhǎng)連接肾砂。
- 如果server要主動(dòng)給client發(fā)數(shù)據(jù)列赎,則選擇長(zhǎng)連接。