之前我們提到了流式套接字和數(shù)據(jù)報(bào)式套接字,在介紹中,我們說(shuō)到了流式套接字是面向連接的套接字,數(shù)據(jù)報(bào)套接字是面向無(wú)連接的套接字。那么面向連接的和面向無(wú)連接的套接字有什么區(qū)別呢?
舉個(gè)例子簡(jiǎn)單地說(shuō)明面向連接就像有一條管道連接著發(fā)送端和接收端,數(shù)據(jù)包都通過(guò)這條管道來(lái)傳輸。當(dāng)然,兩臺(tái)計(jì)算機(jī)在通信之前必須先搭建好管道。
無(wú)連接就像無(wú)頭蒼蠅亂飛,數(shù)據(jù)包從發(fā)送端到接收端并沒(méi)有固定的線(xiàn)路,想怎么走就怎么走,只要能到達(dá)就行。每個(gè)數(shù)據(jù)包都比較自私,不和別人分享自己的線(xiàn)路,但是,大家最終都能到達(dá)接收端。
為了大家能夠更深入的理解,我將為大家用圖示說(shuō)明。
上圖是一個(gè)簡(jiǎn)化互聯(lián)網(wǎng)模型,H1 ~ H6 表示計(jì)算機(jī),A~E 表示路由器,發(fā)送端發(fā)送的數(shù)據(jù)必須經(jīng)過(guò)路由器的轉(zhuǎn)發(fā)才能到達(dá)接收端。
假設(shè) H1 要發(fā)送若干個(gè)數(shù)據(jù)包給 H6,那么有多條路徑可以選擇,比如:
路徑①:H1 --> A --> C --> E --> H6
路徑②:H1 --> A --> B --> E --> H
路徑③:H1 --> A --> B --> D --> E --> H6
路徑④:H1 --> A --> B --> C --> E --> H6
路徑⑤:H1 --> A --> C --> B --> D --> E --> H6
面向連接套接字
面向連接的套接字在正式通信之前要先確定一條路徑,沒(méi)有特殊情況的話(huà),以后就固定使用這條路徑來(lái)傳遞數(shù)據(jù)包了。當(dāng)然,路徑被破壞的話(huà),比如某個(gè)路由器斷電了,那么會(huì)重新建立路徑。
很多網(wǎng)絡(luò)通信教程中,這條預(yù)先建立好的路徑被稱(chēng)為“虛電路”,就是一條虛擬的通信電路。
為了保證數(shù)據(jù)包準(zhǔn)確、順序地到達(dá),發(fā)送端在發(fā)送數(shù)據(jù)包以后,必須得到接收端的確認(rèn)才能發(fā)送下一個(gè)數(shù)據(jù)包;如果數(shù)據(jù)包已經(jīng)發(fā)出去了,在數(shù)據(jù)包發(fā)出去的一段時(shí)間后仍沒(méi)有接收端的回應(yīng),那么發(fā)送端就會(huì)重新再發(fā)送一次,直到得到接收端的回應(yīng)。這樣就能保證,發(fā)送端發(fā)送的所有數(shù)據(jù)包都能準(zhǔn)確有序地到達(dá)接收端,那么發(fā)送端如何得到接收端的回應(yīng)呢?這就像兩個(gè)小人在互相發(fā)消息的過(guò)程,發(fā)送端小人為每一個(gè)數(shù)據(jù)包分配ID,然后發(fā)送給接收端小人,接收端小人在接收到數(shù)據(jù)包后就會(huì)給發(fā)送端小人也回復(fù)一個(gè)數(shù)據(jù)包,并且回復(fù)發(fā)送端:我接收到了一個(gè)ID是XX的數(shù)據(jù)包,就導(dǎo)致了面向連接的套接字會(huì)比無(wú)連接的套接字多出很多數(shù)據(jù)包。
面向無(wú)連接套接字
面向無(wú)連接的套接字,每個(gè)數(shù)據(jù)包都可以選擇不同的路徑,比如第一個(gè)數(shù)據(jù)包選擇路徑②,第二個(gè)數(shù)據(jù)包選擇路徑④,第三個(gè)數(shù)據(jù)包選擇路徑①……當(dāng)然,它們也可以選擇相同的路徑,但那不過(guò)是拐一年搖一年的感覺(jué),緣分吶。
每個(gè)數(shù)據(jù)包之間都是一個(gè)獨(dú)立的個(gè)體,它們都有著我命由我不由天的氣勢(shì),它們不服管啊,它們非要各走各路,誰(shuí)也不care誰(shuí),但是它們除了迷路的和發(fā)生意外的最后都能到達(dá) H6。可到達(dá)的順序是不確定的,比如:
第一個(gè)數(shù)據(jù)包選擇了一條比較長(zhǎng)的路徑(比如路徑⑤),第三個(gè)數(shù)據(jù)包選擇了一條比較短的路徑(比如路徑①),雖然第一個(gè)數(shù)據(jù)包很早就出發(fā)了,但是走的路比較遠(yuǎn),最終還是晚于第三個(gè)數(shù)據(jù)包達(dá)到。
還有一些意外情況的發(fā)生,比如:
第一個(gè)數(shù)據(jù)包選擇了路徑①,但是路由器C突然斷電了,那它就到不了 H6 了。第三個(gè)數(shù)據(jù)包選擇了路徑②,雖然路不遠(yuǎn),但是太擁堵,以至于它等待的時(shí)間太長(zhǎng),路由器把它丟棄了。
總之,對(duì)于無(wú)連接的套接字,數(shù)據(jù)包在傳輸過(guò)程中會(huì)發(fā)生各種不測(cè),也會(huì)發(fā)生各種奇跡。H1 只負(fù)責(zé)把數(shù)據(jù)包發(fā)出,至于它什么時(shí)候到達(dá),先到達(dá)還是后到達(dá),有沒(méi)有成功到達(dá),H1 都不管了;H6 也沒(méi)有選擇的權(quán)利,只能被動(dòng)接收,收到什么算什么,愛(ài)用不用。
無(wú)連接套接字遵循的是盡最大努力完成任務(wù)的原則,做不到了也沒(méi)辦法。誰(shuí)讓無(wú)連接套接字提供的就是沒(méi)有質(zhì)量保證的服務(wù)呢。人家講究的就是快而廣比如廣播。
C語(yǔ)言網(wǎng)提供由在職研發(fā)工程師或ACM藍(lán)橋杯競(jìng)賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點(diǎn)擊了解:
一點(diǎn)編程也不會(huì)寫(xiě)的:零基礎(chǔ)C語(yǔ)言學(xué)練課程
解決困擾你多年的C語(yǔ)言疑難雜癥特性的C語(yǔ)言進(jìn)階課程
從零到寫(xiě)出一個(gè)爬蟲(chóng)的Python編程課程
只會(huì)語(yǔ)法寫(xiě)不出代碼?手把手帶你寫(xiě)100個(gè)編程真題的編程百練課程
信息學(xué)奧賽或C++選手的 必學(xué)C++課程
藍(lán)橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競(jìng)賽課入門(mén)課程
手把手講解近五年真題的藍(lán)橋杯輔導(dǎo)課程