- UDP:用戶數(shù)據(jù)報(bào)協(xié)議:主要用在實(shí)時(shí)性要求比較高的以及對(duì)質(zhì)量相對(duì)較弱的地方.但是面對(duì)現(xiàn)在高質(zhì)量的線路不會(huì)容易丟包,除非是一些擁塞條件下,如流媒體
- TCP:傳輸控制協(xié)議:是面連接的那么運(yùn)行環(huán)境必然要求其可靠性不可丟包,有良好的擁塞控制機(jī)制如 http ftp telnet等
TCP | UDP | |
---|---|---|
發(fā)送 | 安全送達(dá) | 只管發(fā)送 |
接收與建立連接 | 是(三次握手) | 否(有數(shù)據(jù)包,無需連接) |
數(shù)據(jù)大小 | 無限制 | 每個(gè)數(shù)據(jù)報(bào)64k |
可靠性 | 可靠 | 不可靠 |
速度 | 慢(三次握手才能完成連接) | 快(無需連接) |
應(yīng)用 | 流媒體 |
什么是三次握手?
握手次數(shù) | 具體情況 |
---|---|
1 | 建立連接時(shí),客戶端發(fā)送同步序列編號(hào)到服務(wù)器,并進(jìn)入發(fā)送狀態(tài),等待服務(wù)器確認(rèn) |
2 | 服務(wù)器收到同步序列編號(hào),確認(rèn)并同時(shí)自己也發(fā)送一個(gè)同步序列編號(hào)+確認(rèn)標(biāo)識(shí),此時(shí)服務(wù)器進(jìn)入接收狀態(tài) |
3 | 客戶端收到服務(wù)器發(fā)送的包,并向服務(wù)器發(fā)送確認(rèn)標(biāo)識(shí),隨后連接成功 |
注意:是在連接成功后進(jìn)行數(shù)據(jù)傳輸 |
什么是四次揮手?
揮手次數(shù) | 具體情況 |
---|---|
1 | 客戶端向服務(wù)器發(fā)送一個(gè)帶有結(jié)束標(biāo)記的報(bào)文 |
2 | 服務(wù)器收到報(bào)文后,向客戶端發(fā)送一個(gè)確認(rèn)序號(hào),同時(shí)通知自己相應(yīng)的應(yīng)用程序:對(duì)方要求關(guān)閉連接 |
3 | 服務(wù)器向客戶端發(fā)送一個(gè)帶有結(jié)束標(biāo)記的報(bào)文 |
4 | 客戶端收到報(bào)文后,向服務(wù)器發(fā)送一個(gè)確認(rèn)序號(hào),連接關(guān)閉 |
心跳機(jī)制
心跳機(jī)制是定時(shí)發(fā)送一個(gè)自定義的結(jié)構(gòu)體(心跳包)骨宠,讓對(duì)方知道自己還活著,以確保連接的有效性的機(jī)制。(看下圖)
網(wǎng)絡(luò)中的接收和發(fā)送數(shù)據(jù)都是使用操作系統(tǒng)中的SOCKET進(jìn)行實(shí)現(xiàn)上真。但是如果此套接字已經(jīng)斷開溉跃,那發(fā)送數(shù)據(jù)和接收數(shù)據(jù)的時(shí)候就一定會(huì)有問題茫孔》翟郏可是如何判斷這個(gè)套接字是否還可以使用呢爱致?這個(gè)就需要在系統(tǒng)中創(chuàng)建心跳機(jī)制毁习。其實(shí)TCP中已經(jīng)為我們實(shí)現(xiàn)了一個(gè)叫做心跳的機(jī)制智嚷。如果你設(shè)置了心跳,那TCP就會(huì)在一定的時(shí)間(比如你設(shè)置的是3秒鐘)內(nèi)發(fā)送你設(shè)置的次數(shù)的心跳(比如說2次)纺且,并且此信息不會(huì)影響你自己定義的協(xié)議盏道。所謂“心跳”就是定時(shí)發(fā)送一個(gè)自定義的結(jié)構(gòu)體(心跳包或心跳幀),讓對(duì)方知道自己“在線”隆檀。 以確保鏈接的有效性摇天。
所謂的心跳包就是客戶端定時(shí)發(fā)送簡單的信息給服務(wù)器端告訴它我還在而已。代碼就是每隔幾分鐘發(fā)送一個(gè)固定信息給服務(wù)端恐仑,服務(wù)端收到后回復(fù)一個(gè)固定信息如果服務(wù)端幾分鐘內(nèi)沒有收到客戶端信息則視客戶端斷開泉坐。比如有些通信軟件長時(shí)間不使用,要想知道它的狀態(tài)是在線還是離線就需要心跳包裳仆,定時(shí)發(fā)包收包腕让。發(fā)包方:可以是客戶也可以是服務(wù)端,看哪邊實(shí)現(xiàn)方便合理歧斟。一般是客戶端纯丸。服務(wù)器也可以定時(shí)輪詢發(fā)心跳下去。心跳包之所以叫心跳包是因?yàn)椋核裥奶粯用扛艄潭〞r(shí)間發(fā)一次静袖,以此來告訴服務(wù)器觉鼻,這個(gè)客戶端還活著。事實(shí)上這是為了保持長連接队橙,至于這個(gè)包的內(nèi)容坠陈,是沒有什么特別規(guī)定的,不過一般都是很小的包捐康,或者只包含包頭的一個(gè)空包仇矾。
在TCP的機(jī)制里面,本身是存在有心跳包的機(jī)制的解总,也就是TCP的選項(xiàng)贮匕。系統(tǒng)默認(rèn)是設(shè)置的是2小時(shí)的心跳頻率。但是它檢查不到機(jī)器斷電花枫、網(wǎng)線拔出刻盐、防火墻這些斷線掏膏。而且邏輯層處理斷線可能也不是那么好處理。一般敦锌,如果只是用于比雷罚活還是可以的。心跳包一般來說都是在邏輯層發(fā)送空的包來實(shí)現(xiàn)的供屉。下一個(gè)定時(shí)器行冰,在一定時(shí)間間隔下發(fā)送一個(gè)空包給客戶端,然后客戶端反饋一個(gè)同樣的空包回來伶丐,服務(wù)器如果在一定時(shí)間內(nèi)收不到客戶端發(fā)送過來的反饋包悼做,那就只有認(rèn)定說掉線了。只需要send或者recv一下哗魂,如果結(jié)果為零肛走,則為掉線。
但是录别,在長連接下朽色,有可能很長一段時(shí)間都沒有數(shù)據(jù)往來。理論上說组题,這個(gè)連接是一直保持連接的葫男,但是實(shí)際情況中,如果中間節(jié)點(diǎn)出現(xiàn)什么故障是難以知道的崔列。更要命的是梢褐,有的節(jié)點(diǎn)(防火墻)會(huì)自動(dòng)把一定時(shí)間之內(nèi)沒有數(shù)據(jù)交互的連接給斷掉。在這個(gè)時(shí)候赵讯,就需要我們的心跳包了盈咳,用于維持長連接,北咭恚活鱼响。在獲知了斷線之后,服務(wù)器邏輯可能需要做一些事情组底,比如斷線后的數(shù)據(jù)清理呀丈积,重新連接呀當(dāng)然,這個(gè)自然是要由邏輯層根據(jù)需求去做了斤寇⊥把ⅲ總的來說拥褂,心跳包主要也就是用于長連接的蹦锼活和斷線處理。一般的應(yīng)用下饺鹃,判定時(shí)間在30-40秒比較不錯(cuò)莫秆。如果實(shí)在要求高间雀,那就在6-9秒。
心跳檢測步驟:
1.客戶端每隔一個(gè)時(shí)間間隔發(fā)生一個(gè)探測包給服務(wù)器
2.客戶端發(fā)包時(shí)啟動(dòng)一個(gè)超時(shí)定時(shí)器
3.服務(wù)器端接收到檢測包镊屎,應(yīng)該回應(yīng)一個(gè)包
4.如果客戶機(jī)收到服務(wù)器的應(yīng)答包惹挟,則說明服務(wù)器正常,刪除超時(shí)定時(shí)器
5.如果客戶端的超時(shí)定時(shí)器超時(shí)缝驳,依然沒有收到應(yīng)答包连锯,則說明服務(wù)器掛了
心跳包的發(fā)送,通常有兩種技術(shù)
方法1:應(yīng)用層自己實(shí)現(xiàn)的心跳包
由應(yīng)用程序自己發(fā)送心跳包來檢測連接是否正常用狱,大致的方法是:服務(wù)器在一個(gè) Timer事件中定時(shí) 向客戶端發(fā)送一個(gè)短小精悍的數(shù)據(jù)包运怖,然后啟動(dòng)一個(gè)低級(jí)別的線程,在該線程中不斷檢測客戶端的回應(yīng)夏伊, 如果在一定時(shí)間內(nèi)沒有收到客戶端的回應(yīng)摇展,即認(rèn)為客戶端已經(jīng)掉線;同樣溺忧,如果客戶端在一定時(shí)間內(nèi)沒 有收到服務(wù)器的心跳包咏连,則認(rèn)為連接不可用。方法2:TCP的KeepAlive甭成活機(jī)制
因?yàn)橐紤]到一個(gè)服務(wù)器通常會(huì)連接多個(gè)客戶端祟滴,因此由用戶在應(yīng)用層自己實(shí)現(xiàn)心跳包,代碼較多 且稍顯復(fù)雜歌溉,而利用TCP/IP協(xié)議層為內(nèi)置的KeepAlive功能來實(shí)現(xiàn)心跳功能則簡單得多踱启。 不論是服務(wù)端還是客戶端,一方開啟KeepAlive功能后研底,就會(huì)自動(dòng)在規(guī)定時(shí)間內(nèi)向?qū)Ψ桨l(fā)送心跳包埠偿, 而另一方在收到心跳包后就會(huì)自動(dòng)回復(fù),以告訴對(duì)方我仍然在線榜晦。 因?yàn)殚_啟KeepAlive功能需要消耗額外的寬帶和流量冠蒋,所以TCP協(xié)議層默認(rèn)并不開啟KeepAlive功 能,盡管這微不足道乾胶,但在按流量計(jì)費(fèi)的環(huán)境下增加了費(fèi)用抖剿,另一方面,KeepAlive設(shè)置不合理時(shí)可能會(huì) 因?yàn)槎虝旱木W(wǎng)絡(luò)波動(dòng)而斷開健康的TCP連接识窿。并且斩郎,默認(rèn)的KeepAlive超時(shí)需要7,200,000 MilliSeconds喻频, 即2小時(shí)缩宜,探測次數(shù)為5次。對(duì)于很多服務(wù)端應(yīng)用程序來說,2小時(shí)的空閑時(shí)間太長锻煌。因此妓布,我們需要手工開啟KeepAlive功能并設(shè)置合理的KeepAlive參數(shù)。