日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

TCP是面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議:

面向連接:一定是一對(duì)一才能連接,不能像UDP協(xié)議可以一個(gè)主機(jī)同時(shí)向多個(gè)主機(jī)發(fā)送消息,即一對(duì)多是無法做到的

可靠的:無論的網(wǎng)絡(luò)鏈路中出現(xiàn)了怎樣的鏈路變化,TCP 都可以保證一個(gè)報(bào)文一定能夠到達(dá)接收端

字節(jié)流:消息是沒有邊界的,所以無論消息有多大都可以進(jìn)行傳輸。并且消息是有序的,當(dāng)前一個(gè)消息沒有收到的時(shí)候,即使它先收到了后面的字節(jié)已經(jīng)收到,那么也不能扔給應(yīng)用層去處理,同時(shí)對(duì)重復(fù)的報(bào)文會(huì)自動(dòng)丟棄

TCP頭部格式

序列號(hào):在建立連接時(shí)由計(jì)算機(jī)生成的隨機(jī)數(shù)作為其初始值,通過 SYN 包傳給接收端主機(jī),每發(fā)送一次數(shù)據(jù),就「累加」一次該「數(shù)據(jù)字節(jié)數(shù)」的大小。用來解決網(wǎng)絡(luò)包亂序問題

確認(rèn)應(yīng)答號(hào):指下一次「期望」收到的數(shù)據(jù)的序列號(hào),發(fā)送端收到這個(gè)確認(rèn)應(yīng)答以后可以認(rèn)為在這個(gè)序號(hào)以前的數(shù)據(jù)都已經(jīng)被正常接收。用來解決不丟包的問題

控制位:ACK:該位為 1 時(shí),「確認(rèn)應(yīng)答」的字段變?yōu)橛行В琓CP 規(guī)定除了最初建立連接時(shí)的 SYN 包之外該位必須設(shè)置為 1RST:該位為 1 時(shí),表示 TCP 連接中出現(xiàn)異常必須強(qiáng)制斷開連接SYN:該位為 1 時(shí),表示希望建立連接,并在其「序列號(hào)」的字段進(jìn)行序列號(hào)初始值的設(shè)定FIN:該位為 1 時(shí),表示今后不會(huì)再有數(shù)據(jù)發(fā)送,希望斷開連接。當(dāng)通信結(jié)束希望斷開連接時(shí),通信雙方的主機(jī)之間就可以相互交換 FIN 位置為 1 的 TCP 段

網(wǎng)絡(luò)模型

談一談你對(duì) TCP/IP 四層模型,OSI 七層模型的理解?

OSI參考模型

OSI(Open System Interconnect),即開放式系統(tǒng)互聯(lián)。 一般都叫OSI參考模型,是ISO(國際標(biāo)準(zhǔn)化組織)組織在1985年研究的網(wǎng)絡(luò)互連模型。ISO為了更好的使網(wǎng)絡(luò)應(yīng)用更為普及,推出了OSI參考模型。其含義就是推薦所有公司使用這個(gè)規(guī)范來控制網(wǎng)絡(luò)。這樣所有公司都有相同的規(guī)范,就能互聯(lián)了。

TCP/IP五層模型

TCP/IP五層協(xié)議和OSI的七層協(xié)議對(duì)應(yīng)關(guān)系如下:

TCP狀態(tài)

CLOSED: 表示初始狀態(tài)

LISTEN: 表示服務(wù)器端的某個(gè)SOCKET處于監(jiān)聽狀態(tài),可以接受連接了

SYN_RCVD: 表示接收到了SYN報(bào)文

SYN_SENT: 表示客戶端已發(fā)送SYN報(bào)文

ESTABLISHED:表示連接已經(jīng)建立了

TIME_WAIT:表示收到了對(duì)方的FIN報(bào)文,并發(fā)送出了ACK報(bào)文,就等2MSL后即可回到CLOSED可用狀態(tài)了

CLOSING: 表示你發(fā)送FIN報(bào)文后,并沒有收到對(duì)方的ACK報(bào)文,反而卻也收到了對(duì)方的FIN報(bào)文。如果雙方幾乎在同時(shí)close一個(gè)SOCKET的話,那么就出現(xiàn)了雙方同時(shí)發(fā)送FIN報(bào) 文的情況,也即會(huì)出現(xiàn)CLOSING狀態(tài),表示雙方都正在關(guān)閉SOCKET連接

CLOSE_WAIT: 表示在等待關(guān)閉

如何在 linux 系統(tǒng)中查看 TCP 狀態(tài)?

TCP 的連接狀態(tài)查看,在 Linux 可以通過.NETstat -napt 命令查看:

TIME_WAIT

① 為什么需要 TIME_WAIT 狀態(tài)?

主動(dòng)發(fā)起關(guān)閉連接的一方,才會(huì)有 TIME-WAIT 狀態(tài)。需要 TIME-WAIT 狀態(tài),主要是兩個(gè)原因:

防止具有相同「四元組」的「舊」數(shù)據(jù)包被收到

保證「被動(dòng)關(guān)閉連接」的一方能被正確的關(guān)閉,即保證最后的 ACK 能讓被動(dòng)關(guān)閉方接收,從而幫助其正常關(guān)閉

② TIME_WAIT 過多有什么危害?

如果服務(wù)器有處于 TIME-WAIT 狀態(tài)的 TCP,則說明是由服務(wù)器方主動(dòng)發(fā)起的斷開請(qǐng)求。過多的 TIME-WAIT 狀態(tài)主要的危害有兩種:

第一是內(nèi)存資源占用

第二是對(duì)端口資源的占用,一個(gè) TCP 連接至少消耗一個(gè)本地端口

第二個(gè)危害是會(huì)造成嚴(yán)重的后果的,要知道,端口資源也是有限的,一般可以開啟的端口為 32768~61000,也可以通過如下參數(shù)設(shè)置指定

net.ipv4.ip_local_port_range

如果發(fā)起連接一方的 TIME_WAIT 狀態(tài)過多,占滿了所有端口資源,則會(huì)導(dǎo)致無法創(chuàng)建新連接。

客戶端受端口資源限制:

客戶端TIME_WAIT過多,就會(huì)導(dǎo)致端口資源被占用,因?yàn)槎丝诰?5536個(gè),被占滿就會(huì)導(dǎo)致無法創(chuàng)建新的連接

服務(wù)端受系統(tǒng)資源限制:

由于一個(gè)四元組表示 TCP 連接,理論上服務(wù)端可以建立很多連接,服務(wù)端確實(shí)只監(jiān)聽一個(gè)端口 但是會(huì)把連接扔給處理線程,所以理論上監(jiān)聽的端口可以繼續(xù)監(jiān)聽。但是線程池處理不了那么多一直不斷的連接了。所以當(dāng)服務(wù)端出現(xiàn)大量 TIME_WAIT 時(shí),系統(tǒng)資源被占滿時(shí),會(huì)導(dǎo)致處理不過來新的連接

③ 如何優(yōu)化 TIME_WAIT?

這里給出優(yōu)化 TIME-WAIT 的幾個(gè)方式,都是有利有弊:

打開 net.ipv4.tcp_tw_reuse 和 net.ipv4.tcp_timestamps 選項(xiàng)

net.ipv4.tcp_max_tw_buckets

程序中使用SO_LINGER,應(yīng)用強(qiáng)制使用RST關(guān)閉

④ 為什么 TIME_WAIT 等待的時(shí)間是 2MSL?

MSL 是 Maximum Segment Lifetime,報(bào)文最大生存時(shí)間,它是任何報(bào)文在網(wǎng)絡(luò)上存在的最長時(shí)間,超過這個(gè)時(shí)間報(bào)文將被丟棄。因?yàn)?TCP 報(bào)文基于是 IP 協(xié)議的,而 IP 頭中有一個(gè) TTL 字段,是 IP 數(shù)據(jù)報(bào)可以經(jīng)過的最大路由數(shù),每經(jīng)過一個(gè)處理他的路由器此值就減 1,當(dāng)此值為 0 則數(shù)據(jù)報(bào)將被丟棄,同時(shí)發(fā)送 ICMP 報(bào)文通知源主機(jī)。

MSL 與 TTL 的區(qū)別: MSL 的單位是時(shí)間,而 TTL 是經(jīng)過路由跳數(shù)。所以 MSL 應(yīng)該要大于等于 TTL 消耗為 0 的時(shí)間,以確保報(bào)文已被自然消亡。

TIME_WAIT 等待 2 倍的 MSL,比較合理的解釋是: 網(wǎng)絡(luò)中可能存在來自發(fā)送方的數(shù)據(jù)包,當(dāng)這些發(fā)送方的數(shù)據(jù)包被接收方處理后又會(huì)向?qū)Ψ桨l(fā)送響應(yīng),所以一來一回需要等待 2 倍的時(shí)間。

比如如果被動(dòng)關(guān)閉方?jīng)]有收到斷開連接的最后的 ACK 報(bào)文,就會(huì)觸發(fā)超時(shí)重發(fā) Fin 報(bào)文,另一方接收到 FIN 后,會(huì)重發(fā) ACK 給被動(dòng)關(guān)閉方, 一來一去正好 2 個(gè) MSL。

2MSL 的時(shí)間是從客戶端接收到 FIN 后發(fā)送 ACK 開始計(jì)時(shí)的。如果在 TIME-WAIT 時(shí)間內(nèi),因?yàn)榭蛻舳说?ACK 沒有傳輸?shù)椒?wù)端,客戶端又接收到了服務(wù)端重發(fā)的 FIN 報(bào)文,那么 2MSL 時(shí)間將重新計(jì)時(shí)。

在 Linux 系統(tǒng)里 2MSL 默認(rèn)是 60 秒,那么一個(gè) MSL 也就是 30 秒。Linux 系統(tǒng)停留在 TIME_WAIT 的時(shí)間為固定的 60 秒。

其定義在 Linux 內(nèi)核代碼里的名稱為 TCP_TIMEWAIT_LEN:

#define TCP_TIMEWAIT_LEN (60HZ) / how long to wait to destroy TIME-WAIT state, about 60 seconds */

如果要修改TIME_WAIT的時(shí)間長度,只能修改Linux內(nèi)核代碼里TCP_TIMEWAIT_LEN的值,并重新編譯Linux內(nèi)核。

連接過程

TCP三次握手

開始客戶端和服務(wù)器都處于CLOSED狀態(tài),然后服務(wù)端開始監(jiān)聽某個(gè)端口,進(jìn)入LISTEN狀態(tài):

第一次握手(SYN=1, seq=x),發(fā)送完畢后,客戶端進(jìn)入 SYN_SENT 狀態(tài)

第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1), 發(fā)送完畢后,服務(wù)器端進(jìn)入 SYN_RCVD 狀態(tài)

第三次握手(ACK=1,ACKnum=y+1),發(fā)送完畢后,客戶端進(jìn)入 ESTABLISHED 狀態(tài),當(dāng)服務(wù)器端接收到這個(gè)包時(shí),也進(jìn)入 ESTABLISHED 狀態(tài),TCP 握手,即可以開始數(shù)據(jù)傳輸

假設(shè)一開始客戶端和服務(wù)端都處于CLOSED的狀態(tài)。然后先是服務(wù)端主動(dòng)監(jiān)聽某個(gè)端口,處于LISTEN狀態(tài)

【第一個(gè)報(bào)文】:客戶端會(huì)隨機(jī)初始化序號(hào)(client_isn),將此序號(hào)置于 TCP 首部的「序號(hào)」字段中,同時(shí)把 SYN 標(biāo)志位置為 1 ,表示 SYN 報(bào)文。接著把第一個(gè) SYN 報(bào)文發(fā)送給服務(wù)端,表示向服務(wù)端發(fā)起連接,該報(bào)文不包含應(yīng)用層數(shù)據(jù),之后客戶端處于 SYN-SENT 狀態(tài)

【第二個(gè)報(bào)文】:服務(wù)端收到客戶端的 SYN 報(bào)文后,首先服務(wù)端也隨機(jī)初始化自己的序號(hào)(server_isn),將此序號(hào)填入 TCP 首部的「序號(hào)」字段中,其次把 TCP 首部的「確認(rèn)應(yīng)答號(hào)」字段填入 client_isn + 1, 接著把 SYN 和 ACK 標(biāo)志位置為 1。最后把該報(bào)文發(fā)給客戶端,該報(bào)文也不包含應(yīng)用層數(shù)據(jù),之后服務(wù)端處于 SYN-RCVD 狀態(tài)

【第三個(gè)報(bào)文】:客戶端收到服務(wù)端報(bào)文后,還要向服務(wù)端回應(yīng)最后一個(gè)應(yīng)答報(bào)文,首先該應(yīng)答報(bào)文 TCP 首部 ACK 標(biāo)志位置為 1 ,其次「確認(rèn)應(yīng)答號(hào)」字段填入 server_isn + 1 ,最后把報(bào)文發(fā)送給服務(wù)端,這次報(bào)文可以攜帶客戶到服務(wù)器的數(shù)據(jù),之后客戶端處于 ESTABLISHED 狀態(tài)

服務(wù)器收到客戶端的應(yīng)答報(bào)文后,也進(jìn)入 ESTABLISHED 狀態(tài)

第三次握手是否可以攜帶數(shù)據(jù)?

第三次握手是可以攜帶數(shù)據(jù)的,前兩次握手是不可以攜帶數(shù)據(jù)的。一旦完成三次握手,雙方都處于 ESTABLISHED 狀態(tài),此時(shí)連接就已建立完成,客戶端和服務(wù)端就可以相互發(fā)送數(shù)據(jù)了。假設(shè)第三次握手的報(bào)文的seq是x+1:

如果有攜帶數(shù)據(jù):下次客戶端發(fā)送的報(bào)文,seq=服務(wù)器發(fā)回的ACK號(hào)

如果沒有攜帶數(shù)據(jù):第三次握手的報(bào)文不消耗seq,下次客戶端發(fā)送的報(bào)文,seq序列號(hào)為x+1

① 服務(wù)端SYN-RECV流程

② 客戶端SYN-SEND流程

場景1:sk->sk_write_pending != 0

這個(gè)值默認(rèn)是0的,那什么情況會(huì)導(dǎo)致不為0呢?答案是協(xié)議棧發(fā)送數(shù)據(jù)的函數(shù)遇到socket狀態(tài)不是ESTABLISHED的時(shí)候,會(huì)對(duì)這個(gè)變量做++操作,并等待一小會(huì)時(shí)間嘗試發(fā)送數(shù)據(jù)。

場景2:icsk->icsk_accept_queue.rskq_defer_accept != 0

客戶端先bind到一個(gè)端口和IP,然后setsockopt(TCP_DEFER_ACCEPT),然后connect服務(wù)器,這個(gè)時(shí)候就會(huì)出現(xiàn)rskq_defer_accept=1的情況,這時(shí)候內(nèi)核會(huì)設(shè)置定時(shí)器等待數(shù)據(jù)一起在回復(fù)ACK包。

場景3:icsk->icsk_ack.pingpong != 0

pingpong這個(gè)屬性實(shí)際上也是一個(gè)套接字選項(xiàng),用來表明當(dāng)前鏈接是否為交互數(shù)據(jù)流,如其值為1,則表明為交互數(shù)據(jù)流,會(huì)使用延遲確認(rèn)機(jī)制。

為什么是三次握手?不是兩次、四次?

TCP建立連接時(shí),通過三次握手能防止歷史連接的建立,能減少雙方不必要的資源開銷,能幫助雙方同步初始化序列號(hào)。序列號(hào)能夠保證數(shù)據(jù)包不重復(fù)、不丟棄和按序傳輸。不使用「兩次握手」和「四次握手」的原因:

兩次握手:無法防止歷史連接的建立,會(huì)造成雙方資源的浪費(fèi),也無法可靠的同步雙方序列號(hào)

四次握手:三次握手就已經(jīng)理論上最少可靠連接建立,所以不需要使用更多的通信次數(shù)

接下來以三個(gè)方面分析三次握手的原因:

三次握手才可以阻止重復(fù)歷史連接的初始化(主要原因)

三次握手才可以同步雙方的初始序列號(hào)

三次握手才可以避免資源浪費(fèi)

原因一:避免歷史連接

客戶端連續(xù)發(fā)送多次 SYN 建立連接的報(bào)文,在網(wǎng)絡(luò)擁堵情況下:

一個(gè)「舊 SYN 報(bào)文」比「最新的 SYN 」 報(bào)文早到達(dá)了服務(wù)端

那么此時(shí)服務(wù)端就會(huì)回一個(gè) SYN + ACK 報(bào)文給客戶端

客戶端收到后可以根據(jù)自身的上下文,判斷這是一個(gè)歷史連接(序列號(hào)過期或超時(shí)),那么客戶端就會(huì)發(fā)送 RST 報(bào)文給服務(wù)端,表示中止這一次連接

如果是兩次握手連接,就不能判斷當(dāng)前連接是否是歷史連接,三次握手則可以在客戶端(發(fā)送方)準(zhǔn)備發(fā)送第三次報(bào)文時(shí),客戶端因有足夠的上下文來判斷當(dāng)前連接是否是歷史連接:

如果是歷史連接(序列號(hào)過期或超時(shí)),則第三次握手發(fā)送的報(bào)文是 RST 報(bào)文,以此中止歷史連接

如果不是歷史連接,則第三次發(fā)送的報(bào)文是 ACK 報(bào)文,通信雙方就會(huì)成功建立連接

所以,TCP 使用三次握手建立連接的最主要原因是防止歷史連接初始化了連接。

原因二:同步雙方初始序列號(hào)

TCP 協(xié)議的通信雙方, 都必須維護(hù)一個(gè)「序列號(hào)」, 序列號(hào)是可靠傳輸?shù)囊粋€(gè)關(guān)鍵因素,它的作用:

接收方可以去除重復(fù)的數(shù)據(jù)

接收方可以根據(jù)數(shù)據(jù)包的序列號(hào)按序接收

可以標(biāo)識(shí)發(fā)送出去的數(shù)據(jù)包中, 哪些是已經(jīng)被對(duì)方收到的

可見,序列號(hào)在 TCP 連接中占據(jù)著非常重要的作用,所以當(dāng)客戶端發(fā)送攜帶「初始序列號(hào)」的 SYN 報(bào)文的時(shí)候,需要服務(wù)端回一個(gè) ACK 應(yīng)答報(bào)文,表示客戶端的 SYN 報(bào)文已被服務(wù)端成功接收,那當(dāng)服務(wù)端發(fā)送「初始序列號(hào)」給客戶端的時(shí)候,依然也要得到客戶端的應(yīng)答回應(yīng),這樣一來一回,才能確保雙方的初始序列號(hào)能被可靠的同步。

四次握手其實(shí)也能夠可靠的同步雙方的初始化序號(hào),但由于第二步和第三步可以優(yōu)化成一步,所以就成了「三次握手」。而兩次握手只保證了一方的初始序列號(hào)能被對(duì)方成功接收,沒辦法保證雙方的初始序列號(hào)都能被確認(rèn)接收。

原因三:避免資源浪費(fèi)

如果只有「兩次握手」,當(dāng)客戶端的 SYN 請(qǐng)求連接在網(wǎng)絡(luò)中阻塞,客戶端沒有接收到 ACK 報(bào)文,就會(huì)重新發(fā)送 SYN ,由于沒有第三次握手,服務(wù)器不清楚客戶端是否收到了自己發(fā)送的建立連接的 ACK 確認(rèn)信號(hào),所以每收到一個(gè) SYN 就只能先主動(dòng)建立一個(gè)連接,這會(huì)造成什么情況呢?如果客戶端的 SYN 阻塞了,重復(fù)發(fā)送多次 SYN 報(bào)文,那么服務(wù)器在收到請(qǐng)求后就會(huì)建立多個(gè)冗余的無效鏈接,造成不必要的資源浪費(fèi)。

即兩次握手會(huì)造成消息滯留情況下,服務(wù)器重復(fù)接受無用的連接請(qǐng)求 SYN 報(bào)文,而造成重復(fù)分配資源。

TCP四次揮手

第一次揮手:FIN=1,seq=u,發(fā)送完畢后客戶端進(jìn)入FIN_WAIT_1 狀態(tài)

第二次揮手:ACK=1,seq =v,ack=u+1,發(fā)送完畢后服務(wù)器端進(jìn)入CLOSE_WAIT 狀態(tài),客戶端接收到后進(jìn)入 FIN_WAIT_2 狀態(tài)

第三次揮手:FIN=1,ACK=1,seq=w,ack=u+1,發(fā)送完畢后服務(wù)器端進(jìn)入LAST_ACK狀態(tài),客戶端接收到后進(jìn)入 TIME_WAIT狀態(tài)

第四次揮手:ACK=1,seq=u+1,ack=w+1,客戶端接收到來自服務(wù)器端的關(guān)閉請(qǐng)求,發(fā)送一個(gè)確認(rèn)包,并進(jìn)入 TIME_WAIT狀態(tài),等待了某個(gè)固定時(shí)間(兩個(gè)最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,沒有收到服務(wù)器端的 ACK ,認(rèn)為服務(wù)器端已經(jīng)正常關(guān)閉連接,于是自己也關(guān)閉連接,進(jìn)入 CLOSED 狀態(tài)。服務(wù)器端接收到這個(gè)確認(rèn)包之后,關(guān)閉連接,進(jìn)入 CLOSED 狀態(tài)

四次揮手過程:

客戶端打算關(guān)閉連接,此時(shí)會(huì)發(fā)送一個(gè) TCP 首部 FIN 標(biāo)志位被置為 1 的報(bào)文,也即 FIN 報(bào)文,之后客戶端進(jìn)入 FIN_WAIT_1 狀態(tài)

服務(wù)端收到該報(bào)文后,就向客戶端發(fā)送 ACK 應(yīng)答報(bào)文,接著服務(wù)端進(jìn)入 CLOSED_WAIT 狀態(tài)

客戶端收到服務(wù)端的 ACK 應(yīng)答報(bào)文后,之后進(jìn)入 FIN_WAIT_2 狀態(tài)

等待服務(wù)端處理完數(shù)據(jù)后,也向客戶端發(fā)送 FIN 報(bào)文,之后服務(wù)端進(jìn)入 LAST_ACK 狀態(tài)

客戶端收到服務(wù)端的 FIN 報(bào)文后,回一個(gè) ACK 應(yīng)答報(bào)文,之后進(jìn)入 TIME_WAIT 狀態(tài)

服務(wù)器收到了 ACK 應(yīng)答報(bào)文后,就進(jìn)入了 CLOSE 狀態(tài),至此服務(wù)端已經(jīng)完成連接的關(guān)閉

客戶端在經(jīng)過 2MSL 一段時(shí)間后,自動(dòng)進(jìn)入 CLOSE 狀態(tài),至此客戶端也完成連接的關(guān)閉

為什么揮手需要四次?

再來回顧下四次揮手雙方發(fā) FIN 包的過程,就能理解為什么需要四次了。

關(guān)閉連接時(shí),客戶端向服務(wù)端發(fā)送 FIN 時(shí),僅僅表示客戶端不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù)。

服務(wù)器收到客戶端的 FIN 報(bào)文時(shí),先回一個(gè) ACK 應(yīng)答報(bào)文,而服務(wù)端可能還有數(shù)據(jù)需要處理和發(fā)送,等服務(wù)端不再發(fā)送數(shù)據(jù)時(shí),才發(fā)送 FIN 報(bào)文給客戶端來表示同意現(xiàn)在關(guān)閉連接。

從上面過程可知,服務(wù)端通常需要等待完成數(shù)據(jù)的發(fā)送和處理,所以服務(wù)端的 ACK 和 FIN 一般都會(huì)分開發(fā)送,從而比三次握手導(dǎo)致多了一次。

TCP優(yōu)化

正確有效的使用TCP參數(shù)可以提高 TCP 性能。以下將從三個(gè)角度來闡述提升 TCP 的策略,分別是:

TCP三次握手優(yōu)化

TCP四次揮手優(yōu)化

TCP數(shù)據(jù)傳輸優(yōu)化

常見問題

TCP和UDP

TCP和UDP的區(qū)別?

連接TCP 是面向連接的傳輸層協(xié)議,傳輸數(shù)據(jù)前先要建立連接UDP 是不需要連接,即刻傳輸數(shù)據(jù)

服務(wù)對(duì)象TCP 是一對(duì)一的兩點(diǎn)服務(wù),即一條連接只有兩個(gè)端點(diǎn)UDP 支持一對(duì)一、一對(duì)多、多對(duì)多的交互通信

可靠性TCP 是可靠交付數(shù)據(jù)的,數(shù)據(jù)可以無差錯(cuò)、不丟失、不重復(fù)、按需到達(dá)UDP 是盡最大努力交付,不保證可靠交付數(shù)據(jù)

擁塞控制、流量控制TCP 有擁塞控制和流量控制機(jī)制,保證數(shù)據(jù)傳輸?shù)陌踩訳DP 則沒有,即使網(wǎng)絡(luò)非常擁堵了,也不會(huì)影響 UDP 的發(fā)送速率

首部開銷TCP 首部長度較長,會(huì)有一定的開銷,首部在沒有使用「選項(xiàng)」字段時(shí)是 20 個(gè)字節(jié),如果使用了「選項(xiàng)」字段則會(huì)變長的UDP 首部只有 8 個(gè)字節(jié),并且是固定不變的,開銷較小

傳輸方式TCP 是流式傳輸,沒有邊界,但保證順序和可靠UDP 是一個(gè)包一個(gè)包的發(fā)送,是有邊界的,但可能會(huì)丟包和亂序

分片不同TCP 的數(shù)據(jù)大小如果大于 MSS 大小,則會(huì)在傳輸層進(jìn)行分片,目標(biāo)主機(jī)收到后,也同樣在傳輸層組裝 TCP 數(shù)據(jù)包,如果中途丟失了一個(gè)分片,只需要傳輸丟失的這個(gè)分片UDP 的數(shù)據(jù)大小如果大于 MTU 大小,則會(huì)在 IP 層進(jìn)行分片,目標(biāo)主機(jī)收到后,在 IP 層組裝完數(shù)據(jù),接著再傳給傳輸層,但是如果中途丟了一個(gè)分片,則就需要重傳所有的數(shù)據(jù)包,這樣傳輸效率非常差,所以通常 UDP 的報(bào)文應(yīng)該小于 MTU

ISN

① 為什么客戶端和服務(wù)端的初始序列號(hào) ISN 是不相同的?

如果一個(gè)已經(jīng)失效的連接被重用了,但是該舊連接的歷史報(bào)文還殘留在網(wǎng)絡(luò)中,如果序列號(hào)相同,那么就無法分辨出該報(bào)文是不是歷史報(bào)文,如果歷史報(bào)文被新的連接接收了,則會(huì)產(chǎn)生數(shù)據(jù)錯(cuò)亂。所以,每次建立連接前重新初始化一個(gè)序列號(hào)主要是為了通信雙方能夠根據(jù)序號(hào)將不屬于本連接的報(bào)文段丟棄。另一方面是為了安全性,防止黑客偽造的相同序列號(hào)的 TCP 報(bào)文被對(duì)方接收。

② 初始序列號(hào) ISN 是如何隨機(jī)產(chǎn)生的?

起始 ISN 是基于時(shí)鐘的,每 4 毫秒 + 1,轉(zhuǎn)一圈要 4.55 個(gè)小時(shí)。RFC1948 中提出了一個(gè)較好的初始化序列號(hào) ISN 隨機(jī)生成算法。

ISN = M + F (localhost, localport, remotehost, remoteport)

M 是一個(gè)計(jì)時(shí)器,這個(gè)計(jì)時(shí)器每隔 4 毫秒加 1

F 是一個(gè) Hash 算法,根據(jù)源 IP、目的 IP、源端口、目的端口生成一個(gè)隨機(jī)數(shù)值。要保證 Hash 算法不能被外部輕易推算得出,用 MD5 算法是一個(gè)比較好的選擇

UDP

總結(jié)

TCP 向上層提供面向連接的可靠服務(wù) ,UDP 向上層提供無連接不可靠服務(wù)

UDP 沒有 TCP 傳輸可靠,但是可以在實(shí)時(shí)性要求搞的地方有所作為

對(duì)數(shù)據(jù)準(zhǔn)確性要求高,速度可以相對(duì)較慢的,可以選用TCP

TCP數(shù)據(jù)可靠性

一句話:通過校驗(yàn)和、序列號(hào)、確認(rèn)應(yīng)答、超時(shí)重傳、連接管理、流量控制、擁塞控制等機(jī)制來保證可靠性。

(1)校驗(yàn)和

在數(shù)據(jù)傳輸過程中,將發(fā)送的數(shù)據(jù)段都當(dāng)做一個(gè)16位的整數(shù),將這些整數(shù)加起來,并且前面的進(jìn)位不能丟棄,補(bǔ)在最后,然后取反,得到校驗(yàn)和。

發(fā)送方:在發(fā)送數(shù)據(jù)之前計(jì)算校驗(yàn)和,并進(jìn)行校驗(yàn)和的填充。接收方:收到數(shù)據(jù)后,對(duì)數(shù)據(jù)以同樣的方式進(jìn)行計(jì)算,求出校驗(yàn)和,與發(fā)送方進(jìn)行比較。

(2)序列號(hào)

TCP 傳輸時(shí)將每個(gè)字節(jié)的數(shù)據(jù)都進(jìn)行了編號(hào),這就是序列號(hào)。序列號(hào)的作用不僅僅是應(yīng)答作用,有了序列號(hào)能夠?qū)⒔邮盏降臄?shù)據(jù)根據(jù)序列號(hào)進(jìn)行排序,并且去掉重復(fù)的數(shù)據(jù)。

(3)確認(rèn)應(yīng)答

TCP 傳輸過程中,每次接收方接收到數(shù)據(jù)后,都會(huì)對(duì)傳輸方進(jìn)行確認(rèn)應(yīng)答,也就是發(fā)送 ACK 報(bào)文,這個(gè) ACK 報(bào)文中帶有對(duì)應(yīng)的確認(rèn)序列號(hào),告訴發(fā)送方,接收了哪些數(shù)據(jù),下一次數(shù)據(jù)從哪里傳。

(4)超時(shí)重傳

在進(jìn)行 TCP 傳輸時(shí),由于存在確認(rèn)應(yīng)答與序列號(hào)機(jī)制,也就是說發(fā)送方發(fā)送一部分?jǐn)?shù)據(jù)后,都會(huì)等待接收方發(fā)送的 ACK 報(bào)文,并解析 ACK 報(bào)文,判斷數(shù)據(jù)是否傳輸成功。如果發(fā)送方發(fā)送完數(shù)據(jù)后,遲遲都沒有接收到接收方傳來的 ACK 報(bào)文,那么就對(duì)剛剛發(fā)送的數(shù)據(jù)進(jìn)行重發(fā)。

(5)連接管理

就是指三次握手、四次揮手的過程。

(6)流量控制

如果發(fā)送方的發(fā)送速度太快,會(huì)導(dǎo)致接收方的接收緩沖區(qū)填充滿了,這時(shí)候繼續(xù)傳輸數(shù)據(jù),就會(huì)造成大量丟包,進(jìn)而引起丟包重傳等等一系列問題。TCP 支持根據(jù)接收端的處理能力來決定發(fā)送端的發(fā)送速度,這就是流量控制機(jī)制。

具體實(shí)現(xiàn)方式:接收端將自己的接收緩沖區(qū)大小放入 TCP 首部的『窗口大小』字段中,通過 ACK 通知發(fā)送端。

(7)擁塞控制

TCP 傳輸過程中一開始就發(fā)送大量數(shù)據(jù),如果當(dāng)時(shí)網(wǎng)絡(luò)非常擁堵,可能會(huì)造成擁堵加劇。所以 TCP 引入了慢啟動(dòng)機(jī)制,在開始發(fā)送數(shù)據(jù)的時(shí)候,先發(fā)少量的數(shù)據(jù)探探路。

TCP協(xié)議如何提高傳輸效率

一句話:TCP 協(xié)議提高效率的方式有滑動(dòng)窗口、快重傳、延遲應(yīng)答、捎帶應(yīng)答等。

(1)滑動(dòng)窗口

如果每一個(gè)發(fā)送的數(shù)據(jù)段,都要收到 ACK 應(yīng)答之后再發(fā)送下一個(gè)數(shù)據(jù)段,這樣的話我們效率很低,大部分時(shí)間都用在了等待 ACK 應(yīng)答上了。

為了提高效率我們可以一次發(fā)送多條數(shù)據(jù),這樣就能使等待時(shí)間大大減少,從而提高性能。窗口大小指的是無需等待確認(rèn)應(yīng)答而可以繼續(xù)發(fā)送數(shù)據(jù)的最大值。

(2)快重傳

快重傳也叫高速重發(fā)控制。

那么如果出現(xiàn)了丟包,需要進(jìn)行重傳。一般分為兩種情況:

情況一:數(shù)據(jù)包已經(jīng)抵達(dá),ACK被丟了。這種情況下,部分ACK丟了并不影響,因?yàn)榭梢酝ㄟ^后續(xù)的ACK進(jìn)行確認(rèn);

情況二:數(shù)據(jù)包直接丟了。發(fā)送端會(huì)連續(xù)收到多個(gè)相同的 ACK 確認(rèn),發(fā)送端立即將對(duì)應(yīng)丟失的數(shù)據(jù)重傳。

(3)延遲應(yīng)答

如果接收數(shù)據(jù)的主機(jī)立刻返回ACK應(yīng)答,這時(shí)候返回的窗口大小可能比較小。

假設(shè)接收端緩沖區(qū)為1M,一次收到了512K的數(shù)據(jù);如果立刻應(yīng)答,返回的窗口就是512K;

但實(shí)際上可能處理端處理速度很快,10ms之內(nèi)就把512K的數(shù)據(jù)從緩存區(qū)消費(fèi)掉了;

在這種情況下,接收端處理還遠(yuǎn)沒有達(dá)到自己的極限,即使窗口再放大一些,也能處理過來;

如果接收端稍微等一會(huì)在應(yīng)答,比如等待200ms再應(yīng)答,那么這個(gè)時(shí)候返回的窗口大小就是1M;

窗口越大,網(wǎng)絡(luò)吞吐量就越大,傳輸效率就越高;我們的目標(biāo)是在保證網(wǎng)絡(luò)不擁塞的情況下盡量提高傳輸效率。

(4)捎帶應(yīng)答

在延遲應(yīng)答的基礎(chǔ)上,很多情況下,客戶端服務(wù)器在應(yīng)用層也是一發(fā)一收的。這時(shí)候常常采用捎帶應(yīng)答的方式來提高效率,而ACK響應(yīng)常常伴隨著數(shù)據(jù)報(bào)文共同傳輸。如:三次握手。

TCP如何處理擁塞

網(wǎng)絡(luò)擁塞現(xiàn)象是指到達(dá)通信網(wǎng)絡(luò)中某一部分的分組數(shù)量過多,使得該部分網(wǎng)絡(luò)來不及處理,以致引起這部分乃至整個(gè)網(wǎng)絡(luò)性能下降的現(xiàn)象,嚴(yán)重時(shí)甚至?xí)?dǎo)致網(wǎng)絡(luò)通信業(yè)務(wù)陷入停頓,即出現(xiàn)死鎖現(xiàn)象。擁塞控制是處理網(wǎng)絡(luò)擁塞現(xiàn)象的一種機(jī)制。

擁塞控制的四個(gè)階段:

慢啟動(dòng)

擁塞避免

快速重傳

快速恢復(fù)

Socket

基于TCP協(xié)議的客戶端和服務(wù)器工作:

服務(wù)端和客戶端初始化 socket,得到文件描述符

服務(wù)端調(diào)用 bind,將綁定在 IP 地址和端口

服務(wù)端調(diào)用 listen,進(jìn)行監(jiān)聽

服務(wù)端調(diào)用 accept,等待客戶端連接

客戶端調(diào)用 connect,向服務(wù)器端的地址和端口發(fā)起連接請(qǐng)求

服務(wù)端 accept 返回用于傳輸?shù)?socket 的文件描述符

客戶端調(diào)用 write 寫入數(shù)據(jù);服務(wù)端調(diào)用 read 讀取數(shù)據(jù)

客戶端斷開連接時(shí),會(huì)調(diào)用 close,那么服務(wù)端 read 讀取數(shù)據(jù)的時(shí)候,就會(huì)讀取到了 EOF,待處理完數(shù)據(jù)后,服務(wù)端調(diào)用 close,表示連接關(guān)閉

listen 時(shí)候參數(shù) backlog 的意義?

Linux內(nèi)核中會(huì)維護(hù)兩個(gè)隊(duì)列:

未完成連接隊(duì)列(SYN 隊(duì)列):接收到一個(gè) SYN 建立連接請(qǐng)求,處于 SYN_RCVD 狀態(tài);

已完成連接隊(duì)列(Accpet 隊(duì)列):已完成 TCP 三次握手過程,處于 ESTABLISHED 狀態(tài);

SYN 隊(duì)列 與 Accpet 隊(duì)列

int listen (int socketfd, int backlog)

參數(shù)一 socketfd 為 socketfd 文件描述符

參數(shù)二 backlog,這參數(shù)在歷史內(nèi)環(huán)版本有一定的變化

在早期Linux內(nèi)核backlog是SYN隊(duì)列大小,也就是未完成的隊(duì)列大小。在Linux內(nèi)核2.2之后,backlog變成accept隊(duì)列,也就是已完成連接建立的隊(duì)列長度,所以現(xiàn)在通常認(rèn)為backlog是accept隊(duì)列。但是上限值是內(nèi)核參數(shù)somaxconn的大小,也就說accpet隊(duì)列長度=min(backlog, somaxconn)。

accept 發(fā)送在三次握手的哪一步?

我們先看看客戶端連接服務(wù)端時(shí),發(fā)送了什么?

客戶端的協(xié)議棧向服務(wù)器端發(fā)送了 SYN 包,并告訴服務(wù)器端當(dāng)前發(fā)送序列號(hào) client_isn,客戶端進(jìn)入 SYNC_SENT 狀態(tài)

服務(wù)器端的協(xié)議棧收到這個(gè)包之后,和客戶端進(jìn)行 ACK 應(yīng)答,應(yīng)答的值為 client_isn+1,表示對(duì) SYN 包 client_isn 的確認(rèn),同時(shí)服務(wù)器也發(fā)送一個(gè) SYN 包,告訴客戶端當(dāng)前我的發(fā)送序列號(hào)為 server_isn,服務(wù)器端進(jìn)入 SYNC_RCVD 狀態(tài)

客戶端協(xié)議棧收到 ACK 之后,使得應(yīng)用程序從 connect 調(diào)用返回,表示客戶端到服務(wù)器端的單向連接建立成功,客戶端的狀態(tài)為 ESTABLISHED,同時(shí)客戶端協(xié)議棧也會(huì)對(duì)服務(wù)器端的 SYN 包進(jìn)行應(yīng)答,應(yīng)答數(shù)據(jù)為 server_isn+1

應(yīng)答包到達(dá)服務(wù)器端后,服務(wù)器端協(xié)議棧使得 accept 阻塞調(diào)用返回,這個(gè)時(shí)候服務(wù)器端到客戶端的單向連接也建立成功,服務(wù)器端也進(jìn)入 ESTABLISHED 狀態(tài)

從上面的描述過程,我們可以得知客戶端 connect 成功返回是在第二次握手,服務(wù)端 accept 成功返回是在三次握手成功之后。

客戶端調(diào)用 close 了,連接是斷開的流程是什么?

我們看看客戶端主動(dòng)調(diào)用了 close,會(huì)發(fā)生什么?

客戶端調(diào)用 close,表明客戶端沒有數(shù)據(jù)需要發(fā)送了,則此時(shí)會(huì)向服務(wù)端發(fā)送FIN報(bào)文,進(jìn)入FIN_WAIT_1狀態(tài)

服務(wù)端接收到了 FIN 報(bào)文,TCP協(xié)議棧會(huì)為 FIN 包插入一個(gè)文件結(jié)束符 EOF 到接收緩沖區(qū)中,應(yīng)用程序可以通過 read 調(diào)用來感知這個(gè) FIN 包。這個(gè) EOF 會(huì)被放在已排隊(duì)等候的其他已接收的數(shù)據(jù)之后,這就意味著服務(wù)端需要處理這種異常情況,因?yàn)镋OF表示在該連接上再無額外數(shù)據(jù)到達(dá)。此時(shí)服務(wù)端進(jìn)入 CLOSE_WAIT 狀態(tài)

接著,當(dāng)處理完數(shù)據(jù)后,自然就會(huì)讀到 EOF,于是也調(diào)用 close 關(guān)閉它的套接字,這會(huì)使得會(huì)發(fā)出一個(gè) FIN 包,之后處于 LAST_ACK 狀態(tài)

客戶端接收到服務(wù)端的 FIN 包,并發(fā)送 ACK 確認(rèn)包給服務(wù)端,此時(shí)客戶端將進(jìn)入 TIME_WAIT 狀態(tài)

服務(wù)端收到 ACK 確認(rèn)包后,就進(jìn)入了最后的 CLOSE 狀態(tài)

客戶端進(jìn)過 2MSL 時(shí)間之后,也進(jìn)入 CLOSE 狀態(tài)

分享到:
標(biāo)簽:TCP
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績?cè)u(píng)定