SOCK_STREAM與SOCK_DGRAM套接字

流格式套接字(SOCK_STREAM)

流格式套接字(Stream Sockets)也叫“面向連接的套接字”吵冒,在代碼中使用 SOCK_STREAM 表示。
SOCK_STREAM 是一種可靠的额划、雙向的通信數(shù)據(jù)流,數(shù)據(jù)可以準(zhǔn)確無誤地到達(dá)另一臺計(jì)算機(jī),如果損壞或丟失别渔,可以重新發(fā)送楣黍。

流格式套接字有自己的糾錯機(jī)制匾灶,在此我們就不討論了。

SOCK_STREAM 有以下幾個特征:
1.數(shù)據(jù)在傳輸過程中不會消失租漂;
2.數(shù)據(jù)是按照順序傳輸?shù)模?br> 3.數(shù)據(jù)的發(fā)送和接收不是同步的(有的教程也稱“不存在數(shù)據(jù)邊界”)阶女。

可以將 SOCK_STREAM 比喻成一條傳送帶颊糜,只要傳送帶本身沒有問題(不會斷網(wǎng)),就能保證數(shù)據(jù)不丟失秃踩;同時(shí)芭析,較晚傳送的數(shù)據(jù)不會先到達(dá),較早傳送的數(shù)據(jù)不會晚到達(dá)吞瞪,這就保證了數(shù)據(jù)是按照順序傳遞的馁启。

傳送帶.gif

為什么流格式套接字可以達(dá)到高質(zhì)量的數(shù)據(jù)傳輸呢?這是因?yàn)樗褂昧?TCP 協(xié)議(The Transmission Control Protocol芍秆,傳輸控制協(xié)議)惯疙,TCP 協(xié)議會控制你的數(shù)據(jù)按照順序到達(dá)并且沒有錯誤。

你也許見過 TCP妖啥,是因?yàn)槟憬?jīng)常聽說“TCP/IP”霉颠。TCP 用來確保數(shù)據(jù)的正確性,IP(Internet Protocol荆虱,網(wǎng)絡(luò)協(xié)議)用來控制數(shù)據(jù)如何從源頭到達(dá)目的地蒿偎,也就是常說的“路由”。

那么怀读,“數(shù)據(jù)的發(fā)送和接收不同步”該如何理解呢诉位?

假設(shè)傳送帶傳送的是水果,接收者需要湊齊 100 個后才能裝袋菜枷,但是傳送帶可能把這 100 個水果分批傳送苍糠,比如第一批傳送 20 個,第二批傳送 50 個啤誊,第三批傳送 30 個岳瞭。接收者不需要和傳送帶保持同步,只要根據(jù)自己的節(jié)奏來裝袋即可蚊锹,不用管傳送帶傳送了幾批瞳筏,也不用每到一批就裝袋一次,可以等到湊夠了 100 個水果再裝袋牡昆。

流格式套接字的內(nèi)部有一個緩沖區(qū)(也就是字符數(shù)組)姚炕,通過 socket 傳輸?shù)臄?shù)據(jù)將保存到這個緩沖區(qū)。接收端在收到數(shù)據(jù)后并不一定立即讀取迁杨,只要數(shù)據(jù)不超過緩沖區(qū)的容量钻心,接收端有可能在緩沖區(qū)被填滿以后一次性地讀取,也可能分成好幾次讀取铅协。

也就是說捷沸,不管數(shù)據(jù)分幾次傳送過來,接收端只需要根據(jù)自己的要求讀取狐史,不用非得在數(shù)據(jù)到達(dá)時(shí)立即讀取痒给。傳送端有自己的節(jié)奏说墨,接收端也有自己的節(jié)奏,它們是不一致的苍柏。

流格式套接字有什么實(shí)際的應(yīng)用場景嗎尼斧?瀏覽器所使用的 http 協(xié)議就基于面向連接的套接字,因?yàn)楸仨氁_保數(shù)據(jù)準(zhǔn)確無誤试吁,否則加載的 HTML 將無法解析棺棵。

數(shù)據(jù)報(bào)格式套接字(SOCK_DGRAM)

數(shù)據(jù)報(bào)格式套接字(Datagram Sockets)也叫“無連接的套接字”,在代碼中使用 SOCK_DGRAM 表示熄捍。
計(jì)算機(jī)只管傳輸數(shù)據(jù)烛恤,不作數(shù)據(jù)校驗(yàn),如果數(shù)據(jù)在傳輸中損壞余耽,或者沒有到達(dá)另一臺計(jì)算機(jī)缚柏,是沒有辦法補(bǔ)救的。也就是說碟贾,數(shù)據(jù)錯了就錯了币喧,無法重傳。

因?yàn)閿?shù)據(jù)報(bào)套接字所做的校驗(yàn)工作少袱耽,所以在傳輸效率方面比流格式套接字要高杀餐。

SOCK_DGRAM 有以下幾個特征:
1.強(qiáng)調(diào)快速傳輸而非傳輸順序;
2.傳輸?shù)臄?shù)據(jù)可能丟失也可能損毀扛邑;
3.限制每次傳輸?shù)臄?shù)據(jù)大辛场;
4.數(shù)據(jù)的發(fā)送和接收是同步的(有的教程也稱“存在數(shù)據(jù)邊界”)蔬崩。

眾所周知,速度是快遞行業(yè)的生命搀暑。用摩托車發(fā)往同一地點(diǎn)的兩件包裹無需保證順序沥阳,只要以最快的速度交給客戶就行。這種方式存在損壞或丟失的風(fēng)險(xiǎn)自点,而且包裹大小有一定限制桐罕。因此,想要傳遞大量包裹桂敛,就得分配發(fā)送功炮。

另外,用兩輛摩托車分別發(fā)送兩件包裹术唬,那么接收者也需要分兩次接收薪伏,所以“數(shù)據(jù)的發(fā)送和接收是同步的”;換句話說粗仓,接收次數(shù)應(yīng)該和發(fā)送次數(shù)相同嫁怀。

總之设捐,數(shù)據(jù)報(bào)套接字是一種不可靠的、不按順序傳遞的塘淑、以追求速度為目的的套接字萝招。

數(shù)據(jù)報(bào)套接字也使用 IP 協(xié)議作路由,但是它不使用 TCP 協(xié)議存捺,而是使用 UDP 協(xié)議(User Datagram Protocol槐沼,用戶數(shù)據(jù)報(bào)協(xié)議)。

QQ 視頻聊天和語音聊天就使用 SOCK_DGRAM 來傳輸數(shù)據(jù)捌治,因?yàn)槭紫纫WC通信的效率母赵,盡量減小延遲,而數(shù)據(jù)的正確性是次要的具滴,即使丟失很小的一部分?jǐn)?shù)據(jù)凹嘲,視頻和音頻也可以正常解析,最多出現(xiàn)噪點(diǎn)或雜音构韵,不會對通信質(zhì)量有實(shí)質(zhì)的影響周蹭。

其實(shí)SOCK_DGRAM 沒有想象中的糟糕,不會頻繁的丟失數(shù)據(jù)疲恢,數(shù)據(jù)錯誤只是小概率事件凶朗。

面向連接和無連接的套接字到底有什么區(qū)別?

流格式套接字(Stream Sockets)就是“面向連接的套接字”显拳,它基于 TCP 協(xié)議棚愤;數(shù)據(jù)報(bào)格式套接字(Datagram Sockets)就是“無連接的套接字”,它基于 UDP 協(xié)議杂数。

這給大家造成一種印象宛畦,面向連接就是可靠的通信,無連接就是不可靠的通信揍移,實(shí)際情況是這樣嗎次和?

另外,不管是哪種數(shù)據(jù)傳輸方式那伐,都得通過整個 Internet 網(wǎng)絡(luò)的物理線路將數(shù)據(jù)傳輸過去踏施,從這個層面理解,所有的 socket都是有物理連接的呀罕邀,為什么還有無連接的 socket 呢畅形?

從字面上理解,面向連接好像有一條管道诉探,它連接發(fā)送端和接收端日熬,數(shù)據(jù)包都通過這條管道來傳輸。當(dāng)然阵具,兩臺計(jì)算機(jī)在通信之前必須先搭建好管道碍遍。

無連接好像沒頭蒼蠅亂撞定铜,數(shù)據(jù)包從發(fā)送端到接收端并沒有固定的線路,愛怎么走就怎么走怕敬,只要能到達(dá)就行揣炕。每個數(shù)據(jù)包都比較自私,不和別人分享自己的線路东跪,但是畸陡,大家最終都能殊途同歸,到達(dá)接收端虽填。


無連接套接字.gif

上圖是一個簡化的互聯(lián)網(wǎng)模型丁恭,H1 ~ H6 表示計(jì)算機(jī),A~E 表示路由器斋日,發(fā)送端發(fā)送的數(shù)據(jù)必須經(jīng)過路由器的轉(zhuǎn)發(fā)才能到達(dá)接收端牲览。

假設(shè) H1 要發(fā)送若干個數(shù)據(jù)包給 H6,那么有多條路徑可以選擇恶守,比如:
路徑①:H1 → A → C → E → H6
路徑②:H1 → A → B → E → H6
路徑③:H1 → A → B → D → E → H6
路徑④:H1 → A → B → C → E → H6
路徑⑤:H1→ A → C --> B → D → E→ H6

數(shù)據(jù)包的傳輸路徑是路由器根據(jù)算法來計(jì)算出來的第献,算法會考慮很多因素,比如網(wǎng)絡(luò)的擁堵狀況兔港、下一個路由器是否忙碌等庸毫。

無連接的套接字

對于無連接的套接字,每個數(shù)據(jù)包可以選擇不同的路徑衫樊,比如第一個數(shù)據(jù)包選擇路徑④飒赃,第二個數(shù)據(jù)包選擇路徑①,第三個數(shù)據(jù)包選擇路徑②等等科侈。當(dāng)然载佳,它們也可以選擇相同的路徑,那也只不過是巧合而已兑徘。

每個數(shù)據(jù)包之間都是獨(dú)立的刚盈,各走各的路,誰也不影響誰挂脑,除了迷路的或者發(fā)生意外的數(shù)據(jù)包,最后都能到達(dá) H6欲侮。但是崭闲,到達(dá)的順序是不確定的,比如:
1.第一個數(shù)據(jù)包選擇了一條比較長的路徑(比如路徑⑤)威蕉,第三個數(shù)據(jù)包選擇了一條比較短的路徑(比如路徑①)刁俭,雖然第一個數(shù)據(jù)包很早就出發(fā)了,但是走的路比較遠(yuǎn)韧涨,最終還是晚于第三個數(shù)據(jù)包達(dá)到牍戚。
2.第一個數(shù)據(jù)包選擇了一條比較短的路徑(比如路徑①)侮繁,第三個數(shù)據(jù)包選擇了一條比較長的路徑(比如路徑⑤),按理說第一個數(shù)據(jù)包應(yīng)該先到達(dá)如孝,但是非常不幸宪哩,第一個數(shù)據(jù)包走的路比較擁堵,這條路上的數(shù)據(jù)量非常大第晰,路由器處理得很慢锁孟,所以它還是晚于第三個數(shù)據(jù)包達(dá)到了。

還有一些意外情況會發(fā)生茁瘦,比如:
1.第一個數(shù)據(jù)包選擇了路徑①品抽,但是路由器C突然斷電了,那它就到不了 H6 了甜熔。
2.第三個數(shù)據(jù)包選擇了路徑②圆恤,雖然路不遠(yuǎn),但是太擁堵腔稀,以至于它等待的時(shí)間太長盆昙,路由器把它丟棄了。

總之烧颖,對于無連接的套接字弱左,數(shù)據(jù)包在傳輸過程中會發(fā)生各種不測,也會發(fā)生各種奇跡炕淮。H1 只負(fù)責(zé)把數(shù)據(jù)包發(fā)出拆火,至于它什么時(shí)候到達(dá),先到達(dá)還是后到達(dá)涂圆,有沒有成功到達(dá)们镜,H1 都不管了;H6 也沒有選擇的權(quán)利润歉,只能被動接收模狭,收到什么算什么,愛用不用踩衩。

無連接套接字遵循的是「盡最大努力交付」的原則嚼鹉,就是盡力而為,實(shí)在做不到了也沒辦法驱富。無連接套接字提供的沒有質(zhì)量保證的服務(wù)锚赤。

面向連接的套接字

面向連接的套接字在正式通信之前要先確定一條路徑,沒有特殊情況的話褐鸥,以后就固定地使用這條路徑來傳遞數(shù)據(jù)包了线脚。當(dāng)然,路徑被破壞的話,比如某個路由器斷電了浑侥,那么會重新建立路徑姊舵。

有連接套接字.gif

這條路徑是由路由器維護(hù)的,路徑上的所有路由器都要存儲該路徑的信息(實(shí)際上只需要存儲上游和下游的兩個路由器的位置就行)寓落,所以路由器是有開銷的括丁。

H1 和 H6 通信完畢后,要斷開連接零如,銷毀路徑躏将,這個時(shí)候路由器也會把之前存儲的路徑信息擦除。

在很多網(wǎng)絡(luò)通信教程中考蕾,這條預(yù)先建立好的路徑被稱為“虛電路”祸憋,就是一條虛擬的通信電路。

為了保證數(shù)據(jù)包準(zhǔn)確肖卧、順序地到達(dá)蚯窥,發(fā)送端在發(fā)送數(shù)據(jù)包以后,必須得到接收端的確認(rèn)才發(fā)送下一個數(shù)據(jù)包塞帐;如果數(shù)據(jù)包發(fā)出去了拦赠,一段時(shí)間以后仍然沒有得到接收端的回應(yīng),那么發(fā)送端會重新再發(fā)送一次葵姥,直到得到接收端的回應(yīng)荷鼠。這樣一來,發(fā)送端發(fā)送的所有數(shù)據(jù)包都能到達(dá)接收端榔幸,并且是按照順序到達(dá)的允乐。

發(fā)送端發(fā)送一個數(shù)據(jù)包,如何得到接收端的確認(rèn)呢削咆?很簡單牍疏,為每一個數(shù)據(jù)包分配一個 ID,接收端接收到數(shù)據(jù)包以后拨齐,再給發(fā)送端返回一個數(shù)據(jù)包鳞陨,告訴發(fā)送端我接收到了 ID 為 xxx 的數(shù)據(jù)包。

面向連接的套接字會比無連接的套接字多出很多數(shù)據(jù)包瞻惋,因?yàn)榘l(fā)送端每發(fā)送一個數(shù)據(jù)包厦滤,接收端就會返回一個數(shù)據(jù)包。此外歼狼,建立連接和斷開連接的過程也會傳遞很多數(shù)據(jù)包馁害。

不但是數(shù)量多了,每個數(shù)據(jù)包也變大了:除了源端口和目的端口蹂匹,面向連接的套接字還包括序號、確認(rèn)信號凹蜈、數(shù)據(jù)偏移限寞、控制標(biāo)志(通常說的 URG忍啸、ACK、PSH履植、RST计雌、SYN、FIN)玫霎、窗口凿滤、校驗(yàn)和、緊急指針庶近、選項(xiàng)等信息翁脆;而無連接的套接字則只包含長度和校驗(yàn)和信息。

有連接的數(shù)據(jù)包比無連接大很多鼻种,這意味著更大的負(fù)載和更大的帶寬反番。許多即時(shí)聊天軟件采用 UDP 協(xié)議(無連接套接字),與此有莫大的關(guān)系叉钥。

兩種套接字各有優(yōu)缺點(diǎn):
1.無連接套接字傳輸效率高罢缸,但是不可靠,有丟失數(shù)據(jù)包投队、搗亂數(shù)據(jù)的風(fēng)險(xiǎn)枫疆;
2.有連接套接字非常可靠敷鸦,萬無一失息楔,但是傳輸效率低,耗費(fèi)資源多轧膘。

參考文章:
套接字有哪些類型钞螟?socket有哪些類型?
套接字有哪些類型谎碍?socket有哪些類型鳞滨?
面向連接和無連接的套接字到底有什么區(qū)別?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蟆淀,一起剝皮案震驚了整個濱河市拯啦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌熔任,老刑警劉巖褒链,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異疑苔,居然都是意外死亡甫匹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兵迅,“玉大人抢韭,你說我怎么就攤上這事』屑” “怎么了刻恭?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長扯夭。 經(jīng)常有香客問我鳍贾,道長,這世上最難降的妖魔是什么交洗? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任骑科,我火速辦了婚禮,結(jié)果婚禮上藕筋,老公的妹妹穿的比我還像新娘纵散。我一直安慰自己,他們只是感情好隐圾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布伍掀。 她就那樣靜靜地躺著,像睡著了一般暇藏。 火紅的嫁衣襯著肌膚如雪蜜笤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天盐碱,我揣著相機(jī)與錄音把兔,去河邊找鬼。 笑死瓮顽,一個胖子當(dāng)著我的面吹牛县好,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播暖混,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼缕贡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拣播?” 一聲冷哼從身側(cè)響起晾咪,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贮配,沒想到半個月后谍倦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡泪勒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年昼蛀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宴猾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡曹洽,死狀恐怖鳍置,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情送淆,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布怕轿,位于F島的核電站偷崩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏撞羽。R本人自食惡果不足惜阐斜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诀紊。 院中可真熱鬧谒出,春花似錦、人聲如沸邻奠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碌宴。三九已至杀狡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贰镣,已是汗流浹背呜象。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留碑隆,地道東北人恭陡。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像上煤,于是被迫代替她去往敵國和親休玩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354