TCP與UDP通信

一随橘、TCP/IP協(xié)議

TCP/IP網(wǎng)絡(luò)協(xié)議分為:應(yīng)用層(Telnet喂分、FTP、e-mail...)机蔗、傳輸層(TCP蒲祈、UDP)、網(wǎng)絡(luò)層(IP萝嘁、ICMP...)梆掸、鏈路層(設(shè)備驅(qū)動程序及接口卡) 四層

傳輸層及其以下的機制由內(nèi)核提供,應(yīng)用層由用戶進程提供牙言,應(yīng)用程序?qū)νㄓ崝?shù)據(jù)的含義進行解釋酸钦,而傳輸層及其以下處理通訊的細節(jié),將數(shù)據(jù)從一臺計算機通過一定的路徑發(fā)送到另一臺計算機咱枉。應(yīng)用層數(shù)據(jù)通過協(xié)議棧發(fā)到網(wǎng)絡(luò)上時卑硫,每層協(xié)議都要加上一個數(shù)據(jù)首部(header),稱為封裝(Encapsulation)

Mou icon

不同的協(xié)議層對數(shù)據(jù)包有不同的稱謂蚕断,在傳輸層叫做段(segment)欢伏,在網(wǎng)絡(luò)層叫做數(shù)據(jù)報 (datagram),在鏈路層叫做幀(frame)亿乳。數(shù)據(jù)封裝成幀后發(fā)到傳輸介質(zhì)上硝拧,到達目的主機后每層協(xié)議再剝掉相應(yīng)的首部,最后將應(yīng)用層數(shù)據(jù)交給應(yīng)用程序處理

Markdown

其實在鏈路層之下還有物理層葛假,指的是電信號的傳遞方式障陶,比如現(xiàn)在以太網(wǎng)通用的網(wǎng)線(雙絞線)、早期以太網(wǎng)采用的的同軸電纜(現(xiàn)在主要用于有線電視)聊训、光纖等都屬于物理層的概念抱究。物理層的能力決定了最大傳輸速率、傳輸距離带斑、抗干擾性等媳维。集線器(Hub)是工作在物理層的網(wǎng)絡(luò)設(shè)備酿雪,用于雙絞線的連接和信號中繼(將已衰減的信號再次放大使之傳得更遠)遏暴。

鏈路層有以太網(wǎng)侄刽、令牌環(huán)網(wǎng)等標(biāo)準(zhǔn),鏈路層負責(zé)網(wǎng)卡設(shè)備的驅(qū)動朋凉、幀同步(就是說從網(wǎng)線上檢測到什么信號算作新幀的開始)州丹、沖突檢測(如果檢測到?jīng)_突就自動重發(fā))、數(shù)據(jù)差錯校驗等工作杂彭。交換機是工作在鏈路層的網(wǎng)絡(luò)設(shè)備墓毒,可以在不同的鏈路層網(wǎng)絡(luò)之間轉(zhuǎn)發(fā)數(shù)據(jù)幀(比如十兆以太網(wǎng)和百兆以太網(wǎng)之間、以太網(wǎng)和令牌環(huán)網(wǎng)之間)亲怠,由于不同鏈路層的幀格式不同所计,交換機要將進來的數(shù)據(jù)包拆掉鏈路層首部重新封裝之后再轉(zhuǎn)發(fā)。

網(wǎng)絡(luò)層的IP協(xié)議是構(gòu)成Internet的基礎(chǔ)团秽。Internet上的主機通過IP地址來標(biāo)識主胧,Internet上有大量路由器負責(zé)根據(jù)IP地址選擇合適的路徑轉(zhuǎn)發(fā)數(shù)據(jù)包,數(shù)據(jù)包從Internet上的源主機到目的主機往往要經(jīng)過十多個路由器习勤。路由器是工作在第三層的網(wǎng)絡(luò)設(shè)備踪栋,同時兼有交換機的功能,可以在不同的鏈路層接口之間轉(zhuǎn)發(fā)數(shù)據(jù)包图毕,因此路由器需要將進來的數(shù)據(jù)包拆掉網(wǎng)絡(luò)層和鏈路層兩層首部并重新封裝夷都。IP協(xié)議不保證傳輸?shù)目煽啃裕瑪?shù)據(jù)包在傳輸過程中可能丟失予颤,可靠性可以在上層協(xié)議或應(yīng)用程序中提供支持囤官。

網(wǎng)絡(luò)層負責(zé)點到點(point-to-point)的傳輸(這里的“點”指主機或路由器),而傳輸層負責(zé)端到端(end-to-end)的傳輸(這里的“端”指源主機和目的主機)蛤虐。傳輸層可選擇TCP或UDP協(xié) 議党饮。TCP是一種面向連接的、可靠的協(xié)議笆焰,有點像打電話劫谅,雙方拿起電話互通身份之后就建立了連接,然后說話就行了嚷掠,這邊說的話那邊保證聽得到捏检,并且是按說話的順序聽到的,說完話掛機斷開連接不皆。也就是說TCP傳輸?shù)碾p方需要首先建立連接贯城,之后由TCP協(xié)議保證數(shù)據(jù)收發(fā)的可靠性,丟失的數(shù)據(jù)包自動重發(fā)霹娄,上層應(yīng)用程序收到的總是可靠的數(shù)據(jù)流能犯,通訊之后關(guān)閉連接鲫骗。UDP協(xié)議不面向連接,也不保證可靠性踩晶,有點像寄信执泰,寫好信放到郵筒里,既不能保證信件在郵遞過程中不會丟失渡蜻,也不能保證信件是按順序寄到目的地的术吝。使用UDP協(xié)議的應(yīng)用程序需要自己完成丟包重發(fā)、消息排序等工作茸苇。

以太網(wǎng)驅(qū)動程序首先根據(jù)以太網(wǎng)首部中的“上層協(xié)議”字段確定該數(shù)據(jù)幀的有效載荷(payload排苍,指除去協(xié)議首部之外實際傳輸?shù)臄?shù)據(jù))是IP、ARP還是RARP協(xié)議的數(shù)據(jù)報学密,然后交給相應(yīng)的協(xié)議處理淘衙。假如是IP數(shù)據(jù)報,IP協(xié)議再根據(jù)IP首部中的“上層協(xié)議”字段確定該數(shù)據(jù)報的有效載荷是TCP腻暮、UDP彤守、ICMP還是IGMP,然后交給相應(yīng)的協(xié)議處理西壮。假如是TCP段 或UDP段遗增,TCP或UDP協(xié)議再根據(jù)TCP首部或UDP首部的“端口號”字段確定應(yīng)該將應(yīng)用層數(shù)據(jù)交給哪個用戶進程。IP地址是標(biāo)識網(wǎng)絡(luò)中不同主機的地址款青,而端口號就是同一臺主機上標(biāo)識不同進程的地址做修,IP地址和端口號合起來標(biāo)識網(wǎng)絡(luò)中唯一的進程。

二抡草、TCP的三次握手與四次揮手

所謂三次握手(Three-Way Handshake)即建立TCP連接饰及,就是指建立一個TCP連接時,需要客戶端和服務(wù)端總共發(fā)送3個包以確認(rèn)連接的建立康震。在socket編程中燎含,這一過程由客戶端執(zhí)行connect來觸發(fā)

(1)第一次握手:Client將標(biāo)志位SYN置為1,隨機產(chǎn)生一個值seq=J腿短,并將該數(shù)據(jù)包發(fā)送給Server屏箍,Client進入SYN_SENT狀態(tài),等待Server確認(rèn)橘忱。

(2)第二次握手:Server收到數(shù)據(jù)包后由標(biāo)志位SYN=1知道Client請求建立連接赴魁,Server將標(biāo)志位SYN和ACK都置為1,ack=J+1钝诚,隨機產(chǎn)生一個值seq=K颖御,并將該數(shù)據(jù)包發(fā)送給Client以確認(rèn)連接請求,Server進入SYN_RCVD狀態(tài)凝颇。

(3)第三次握手:Client收到確認(rèn)后潘拱,檢查ack是否為J+1疹鳄,ACK是否為1,如果正確則將標(biāo)志位ACK置為1芦岂,ack=K+1瘪弓,并將該數(shù)據(jù)包發(fā)送給Server,Server檢查ack是否為K+1盔腔,ACK是否為1杠茬,如果正確則連接建立成功,Client和Server進入ESTABLISHED狀態(tài)弛随,完成三次握手,隨后Client與Server之間可以開始傳輸數(shù)據(jù)了宁赤。

SYN攻擊:
在三次握手過程中舀透,Server發(fā)送SYN-ACK之后,收到Client的ACK之前的TCP連接稱為半連接(half-open connect)决左,此時Server處于SYN_RCVD狀態(tài)愕够,當(dāng)收到ACK后,Server轉(zhuǎn)入ESTABLISHED狀態(tài)佛猛。SYN攻擊就是Client在短時間內(nèi)偽造大量不存在的IP地址惑芭,并向Server不斷地發(fā)送SYN包,Server回復(fù)確認(rèn)包继找,并等待Client的確認(rèn)遂跟,由于源地址是不存在的,因此婴渡,Server需要不斷重發(fā)直至超時幻锁,這些偽造的SYN包將產(chǎn)時間占用未連接隊列,導(dǎo)致正常的SYN請求因為隊列滿而被丟棄边臼,從而引起網(wǎng)絡(luò)堵塞甚至系統(tǒng)癱瘓哄尔。SYN攻擊時一種典型的DDOS攻擊,檢測SYN攻擊的方式非常簡單柠并,即當(dāng)Server上有大量半連接狀態(tài)且源IP地址是隨機的岭接,則可以斷定遭到SYN攻擊了

所謂四次揮手(Four-Way Wavehand)即終止TCP連接,就是指斷開一個TCP連接時臼予,需要客戶端和服務(wù)端總共發(fā)送4個包以確認(rèn)連接的斷開鸣戴。在socket編程中,這一過程由客戶端或服務(wù)端任一方執(zhí)行close來觸發(fā)

由于TCP連接時全雙工的瘟栖,因此葵擎,每個方向都必須要單獨進行關(guān)閉,這一原則是當(dāng)一方完成數(shù)據(jù)發(fā)送任務(wù)后半哟,發(fā)送一個FIN來終止這一方向的連接酬滤,收到一個FIN只是意味著這一方向上沒有數(shù)據(jù)流動了签餐,即不會再收到數(shù)據(jù)了,但是在這個TCP連接上仍然能夠發(fā)送數(shù)據(jù)盯串,直到這一方向也發(fā)送了FIN氯檐。首先進行關(guān)閉的一方將執(zhí)行主動關(guān)閉,而另一方則執(zhí)行被動關(guān)閉

(1)第一次揮手:Client發(fā)送一個FIN体捏,用來關(guān)閉Client到Server的數(shù)據(jù)傳送冠摄,Client進入FIN_WAIT_1狀態(tài)。

(2)第二次揮手:Server收到FIN后几缭,發(fā)送一個ACK給Client河泳,確認(rèn)序號為收到序號+1(與SYN相同,一個FIN占用一個序號)年栓,Server進入CLOSE_WAIT狀態(tài)拆挥。

(3)第三次揮手:Server發(fā)送一個FIN,用來關(guān)閉Server到Client的數(shù)據(jù)傳送某抓,Server進入LAST_ACK狀態(tài)邑雅。

(4)第四次揮手:Client收到FIN后乌叶,Client進入TIME_WAIT狀態(tài)塔鳍,接著發(fā)送一個ACK給Server愕乎,確認(rèn)序號為收到序號+1,Server進入CLOSED狀態(tài)备禀,完成四次揮手洲拇。

三、TCP的客戶端和服務(wù)端實現(xiàn)解析

(1)connect()函數(shù)

對于客戶端的 connect() 函數(shù)痹届,該函數(shù)的功能為客戶端主動連接服務(wù)器呻待,建立連接是通過三次握手,而這個連接的過程是由內(nèi)核完成队腐,不是這個函數(shù)完成的蚕捉,這個函數(shù)的作用僅僅是通知 Linux 內(nèi)核,讓 Linux 內(nèi)核自動完成 TCP 三次握手連接柴淘,最后把連接的結(jié)果返回給這個函數(shù)的返回值(成功連接為0迫淹, 失敗為-1)。

通常的情況为严,客戶端的 connect() 函數(shù)默認(rèn)會一直阻塞敛熬,直到三次握手成功或超時失敗才返回(正常的情況,這個過程很快完成)第股。

(2)listen()函數(shù)
int listen(int sockfd, int backlog); 

對于服務(wù)器应民,它是被動連接的。listen() 函數(shù)的主要作用就是將套接字( sockfd )變成被動的連接監(jiān)聽套接字(被動等待客戶端的連接),至于參數(shù) backlog 的作用是設(shè)置內(nèi)核中連接隊列的長度

這里需要注意的是诲锹,listen()函數(shù)不會阻塞繁仁,它主要做的事情為,將該套接字和套接字對應(yīng)的連接隊列長度告訴 Linux 內(nèi)核归园,然后黄虱,listen()函數(shù)就結(jié)束。

這樣的話庸诱,當(dāng)有一個客戶端主動連接(connect())捻浦,Linux 內(nèi)核就自動完成TCP 3次握手,將建立好的鏈接自動存儲到隊列中桥爽,如此重復(fù)朱灿。

所以,只要 TCP 服務(wù)器調(diào)用了 listen()聚谁,客戶端就可以通過 connect() 和服務(wù)器建立連接母剥,而這個連接的過程是由內(nèi)核完成。

為了更好的理解 backlog 參數(shù)形导,我們必須認(rèn)識到內(nèi)核為任何一個給定的監(jiān)聽套接口維護兩個隊列:

1、未完成連接隊列(incomplete connection queue)习霹,每個這樣的 SYN 分節(jié)對應(yīng)其中一項:已由某個客戶發(fā)出并到達服務(wù)器朵耕,而服務(wù)器正在等待完成相應(yīng)的 TCP三次握手過程。這些套接口處于 SYN_RCVD 狀態(tài)淋叶。

2阎曹、已完成連接隊列(completed connection queue),每個已完成 TCP 三次握手過程的客戶對應(yīng)其中一項煞檩。這些套接口處于 ESTABLISHED 狀態(tài)处嫌。

當(dāng)來自客戶的 SYN 到達時,TCP 在未完成連接隊列中創(chuàng)建一個新項斟湃,然后響應(yīng)以三次握手的第二個分節(jié):服務(wù)器的 SYN 響應(yīng)熏迹,其中稍帶對客戶 SYN 的 ACK(即SYN+ACK),這一項一直保留在未完成連接隊列中凝赛,直到三次握手的第三個分節(jié)(客戶對服務(wù)器 SYN 的 ACK )到達或者該項超時為止(曾經(jīng)源自Berkeley的實現(xiàn)為這些未完成連接的項設(shè)置的超時值為75秒)注暗。

如果三次握手正常完成,該項就從未完成連接隊列移到已完成連接隊列的隊尾墓猎。

backlog 參數(shù)歷史上被定義為上面兩個隊列的大小之和捆昏,大多數(shù)實現(xiàn)默認(rèn)值為 5,當(dāng)服務(wù)器把這個完成連接隊列的某個連接取走后毙沾,這個隊列的位置又空出一個骗卜,這樣來回實現(xiàn)動態(tài)平衡,但在高并發(fā) web 服務(wù)器中此值顯然不夠。

(3)accept()函數(shù)

accept()函數(shù)功能是寇仓,從處于 established 狀態(tài)的連接隊列頭部取出一個已經(jīng)完成的連接举户,如果這個隊列沒有已經(jīng)完成的連接,accept()函數(shù)就會阻塞焚刺,直到取出隊列中已完成的用戶連接為止

Markdown

四敛摘、UDP的實現(xiàn)

與 TCP 不同, UDP 并不提供對 IP 協(xié)議的可靠機制乳愉、流控制以及錯誤恢復(fù) 功能等兄淫。由于 UDP 比較簡單, UDP 頭包含很少的字節(jié)蔓姚,比TCP負載消耗少捕虽。 UDP適用于不需要TCP可靠機制的情形,比如坡脐,當(dāng)高層協(xié)議或應(yīng)用程序提供錯 誤和流控制功能的時候泄私。

UDP套接口是無連接的、不可靠的數(shù)據(jù)報協(xié)議备闲;既然他不可靠為什么還要用呢晌端?其一:當(dāng)應(yīng)用程序使用廣播或多播時只能使用UDP協(xié)議;其二:由于他是無連接的恬砂,所以速度快咧纠。因為UDP套接口是無連接的,如果一方的數(shù)據(jù)報丟失泻骤,那另一方將無限等待漆羔,解決辦法是設(shè)置一個超時。

建立UDP套接口時socket函數(shù)的第二個參數(shù)應(yīng)該是SOCK_DGRAM狱掂,說明是建立一個UDP套接口演痒;

由于UDP是無連接的,所以服務(wù)器端并不需要listen或accept函數(shù)趋惨。

使用UDP套接字編程可以實現(xiàn)基于TCP/IP協(xié)議的面向無連接的通信

Markdown

參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末端姚,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子挤悉,更是在濱河造成了極大的恐慌渐裸,老刑警劉巖巫湘,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異昏鹃,居然都是意外死亡尚氛,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門洞渤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阅嘶,“玉大人,你說我怎么就攤上這事载迄⊙度幔” “怎么了?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵护昧,是天一觀的道長魂迄。 經(jīng)常有香客問我,道長惋耙,這世上最難降的妖魔是什么捣炬? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮绽榛,結(jié)果婚禮上湿酸,老公的妹妹穿的比我還像新娘。我一直安慰自己灭美,他們只是感情好稿械,可當(dāng)我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冲粤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪页眯。 梳的紋絲不亂的頭發(fā)上梯捕,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天,我揣著相機與錄音窝撵,去河邊找鬼傀顾。 笑死,一個胖子當(dāng)著我的面吹牛碌奉,可吹牛的內(nèi)容都是我干的短曾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼赐劣,長吁一口氣:“原來是場噩夢啊……” “哼嫉拐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起魁兼,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤婉徘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盖呼,經(jīng)...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡儒鹿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了几晤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片约炎。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖蟹瘾,靈堂內(nèi)的尸體忽然破棺而出圾浅,到底是詐尸還是另有隱情,我是刑警寧澤热芹,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布贱傀,位于F島的核電站,受9級特大地震影響伊脓,放射性物質(zhì)發(fā)生泄漏府寒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一报腔、第九天 我趴在偏房一處隱蔽的房頂上張望株搔。 院中可真熱鬧,春花似錦纯蛾、人聲如沸纤房。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽炮姨。三九已至,卻和暖如春碰煌,著一層夾襖步出監(jiān)牢的瞬間舒岸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工芦圾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蛾派,地道東北人。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓个少,卻偏偏與公主長得像洪乍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子夜焦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,554評論 2 349

推薦閱讀更多精彩內(nèi)容