iOS socket網(wǎng)絡(luò)編程(一)

在了解socket網(wǎng)絡(luò)編程之前赖歌,我們需要先知道以下幾個問題:

  • 網(wǎng)絡(luò)中進程之間如何通信构资?
  • Socket是什么割坠?
  • TCP和UDP的區(qū)別齐帚?
  • socket中TCP的三次握手和四次握手建立連接詳解
  • iOS socket的基本操作

一、網(wǎng)絡(luò)中進程之間如何通信彼哼?

我們知道兩個進程如果需要進行通訊最基本的一個前提能夠唯一的標(biāo)識一個進程对妄,在本地進程通訊中我們可以使用PID來唯一標(biāo)示一個進程,但PID只在本地唯一沪羔,網(wǎng)絡(luò)中的兩個進程PID沖突幾率很大饥伊,這時候我們需要另辟它徑了,我們知道網(wǎng)絡(luò)層的ip地址可以唯一標(biāo)示主機蔫饰,而傳輸層協(xié)議和端口號可以唯一標(biāo)示主機的一個進程,這樣我們可以利用三元組(ip地址+協(xié)議+端口號)唯一標(biāo)示網(wǎng)絡(luò)中的一個進程愉豺。能夠唯一標(biāo)示網(wǎng)絡(luò)中的進程后篓吁,它們就可以利用Socket進行通信了。

二蚪拦、Socket 是什么杖剪?

上面我們已經(jīng)知道網(wǎng)絡(luò)中的進程是通過socket來通信的,那什么是socket呢驰贷?socket起源于Unix盛嘿,而Unix/Linux基本哲學(xué)之一就是“一切皆文件”,都可以用“打開open –> 讀寫write/read –> 關(guān)閉close”模式來操作括袒。


從這張圖片中次兆,我們可以很直觀的看到Socket的位置。我們經(jīng)常把socket翻譯為套接字锹锰,socket是在應(yīng)用層和傳輸層之間的一個抽象層芥炭,它把TCP/IP層復(fù)雜的操作抽象為幾個簡單的接口供應(yīng)用層調(diào)用已實現(xiàn)進程在網(wǎng)絡(luò)中通信。

三恃慧、TCP和UDP的區(qū)別园蝠?

TCP:面向連接、傳輸可靠(保證數(shù)據(jù)正確性,保證數(shù)據(jù)順序)痢士、用于傳輸大量數(shù)據(jù)(流模式)彪薛、速度慢,建立連接需要開銷較多(時間,系統(tǒng)資源)善延。

UDP:面向非連接训唱、傳輸不可靠、用于傳輸少量數(shù)據(jù)(數(shù)據(jù)包模式)挚冤、速度快况增。

關(guān)于TCP是一種流模式的協(xié)議,UDP是一種數(shù)據(jù)報模式的協(xié)議训挡,這里要說明一下澳骤,TCP是面向連接的,也就是說澜薄,在連接持續(xù)的過程中为肮,socket中收到的數(shù)據(jù)都是由同一臺主機發(fā)出的(劫持什么的不考慮),因此肤京,知道保證數(shù)據(jù)是有序的到達就行了颊艳,至于每次讀取多少數(shù)據(jù)自己看著辦。

而UDP是無連接的協(xié)議忘分,也就是說棋枕,只要知道接收端的IP和端口,且網(wǎng)絡(luò)是可達的妒峦,任何主機都可以向接收端發(fā)送數(shù)據(jù)重斑。這時候,如果一次能讀取超過一個報文的數(shù)據(jù)肯骇,則會亂套窥浪。比如,主機A向發(fā)送了報文P1笛丙,主機B發(fā)送了報文P2漾脂,如果能夠讀取超過一個報文的數(shù)據(jù),那么就會將P1和P2的數(shù)據(jù)合并在了一起胚鸯,這樣的數(shù)據(jù)是沒有意義的骨稿。

TCP三次握手和四次揮手
相對于SOCKET開發(fā)者,TCP創(chuàng)建過程和連接拆除過程是由TCP/IP協(xié)議棧自動創(chuàng)建的蠢琳。因此開發(fā)者并不需要控制這個過程啊终。但是對于理解TCP底層運作機制,相當(dāng)有幫助傲须。

因此在這里詳細(xì)解釋一下這兩個過程蓝牲。

TCP三次握手

所謂三次握手(Three-way Handshake),是指建立一個TCP連接時泰讽,需要客戶端和服務(wù)器總共發(fā)送3個包例衍。

三次握手的目的是連接服務(wù)器指定端口昔期,建立TCP連接,并同步連接雙方的序列號和確認(rèn)號并交換 TCP 窗口大小信息.在socket編程中,客戶端執(zhí)行connect()時佛玄。將觸發(fā)三次握手硼一。


三次握手

首先了解一下幾個標(biāo)志,SYN(synchronous)梦抢,同步標(biāo)志般贼,ACK (Acknowledgement),即確認(rèn)標(biāo)志奥吩,seq應(yīng)該是Sequence Number哼蛆,序列號的意思,另外還有四次握手的fin霞赫,應(yīng)該是final腮介,表示結(jié)束標(biāo)志。

第一次握手:客戶端發(fā)送一個TCP的SYN標(biāo)志位置1的包指明客戶打算連接的服務(wù)器的端口端衰,以及初始序號X,保存在包頭的序列號(Sequence Number)字段里叠洗。

第二次握手:服務(wù)器發(fā)回確認(rèn)包(ACK)應(yīng)答。即SYN標(biāo)志位和ACK標(biāo)志位均為1同時旅东,將確認(rèn)序號(Acknowledgement Number)設(shè)置為客戶的序列號加1以灭抑,即X+1。

第三次握手:客戶端再次發(fā)送確認(rèn)包(ACK) SYN標(biāo)志位為0玉锌,ACK標(biāo)志位為1名挥。并且把服務(wù)器發(fā)來ACK的序號字段+1,放在確定字段中發(fā)送給對方.并且在數(shù)據(jù)段放寫序列號的+1主守。

TCP四次揮手

TCP的連接的拆除需要發(fā)送四個包,因此稱為四次揮手(four-way handshake)榄融〔我客戶端或服務(wù)器均可主動發(fā)起揮手動作,在socket

編程中愧杯,任何一方執(zhí)行close()操作即可產(chǎn)生揮手操作涎才。



其實有個問題,為什么連接的時候是三次握手力九,關(guān)閉的時候卻是四次揮手耍铜?

因為當(dāng)Server端收到Client端的SYN連接請求報文后,可以直接發(fā)送SYN+ACK報文跌前。其中ACK報文是用來應(yīng)答的棕兼,SYN報文是用來同步的。但是關(guān)閉連接時抵乓,當(dāng)Server端收到FIN報文時伴挚,很可能并不會立即關(guān)閉SOCKET靶衍,所以只能先回復(fù)一個ACK報文,告訴Client端茎芋,”你發(fā)的FIN報文我收到了”颅眶。只有等到我Server端所有的報文都發(fā)送完了,我才能發(fā)送FIN報文田弥,因此不能一起發(fā)送涛酗。故需要四步握手。

tcpsocket和udpsocket的具體實現(xiàn)

tcp和udp的socket是有區(qū)別的偷厦,這里給出這兩種的設(shè)計框架商叹。

基本TCP客戶—服務(wù)器程序設(shè)計基本框架:



基本UDP客戶—服務(wù)器程序設(shè)計基本框架流程圖:


常用的Socket類型有兩種:流式Socket(SOCK_STREAM)和數(shù)據(jù)報式Socket(SOCK_DGRAM)。流式是一種面向連接的Socket沪哺,針對于面向連接的TCP服務(wù)應(yīng)用沈自;數(shù)據(jù)報式Socket是一種無連接的Socket,對應(yīng)于無連接的UDP服務(wù)應(yīng)用辜妓。

四枯途、 iOS socket的基本操作

講了這么久,終于要開始講socket的具體實現(xiàn)了籍滴,iOS提供了Socket網(wǎng)絡(luò)編程的接口CFSocket酪夷,不過這里使用BSD Socket。iOS網(wǎng)絡(luò)編程層次結(jié)構(gòu)也分為三層:

  • Cocoa層:NSURL孽惰,Bonjour晚岭,Game Kit,WebKit
  • Core Foundation層:基于 C 的 CFNetwork 和 CFNetServices
  • OS層:基于 C 的 BSD socket

Cocoa層:是最上層的基于 Objective-C 的 API勋功,比如 URL訪問坦报,NSStream,Bonjour狂鞋,GameKit等片择,這是大多數(shù)情況下我們常用的 API。Cocoa 層是基于 Core Foundation 實現(xiàn)的骚揍。

Core Foundation層:因為直接使用 socket 需要更多的編程工作字管,所以蘋果對 OS 層的 socket 進行簡單的封裝以簡化編程任務(wù)。該層提供了 CFNetwork 和 CFNetServices信不,其中 CFNetwork 又是基于 CFStream 和 CFSocket嘲叔。

OS層:最底層的 BSD socket 提供了對網(wǎng)絡(luò)編程最大程度的控制,但是編程工作也是最多的抽活。因此硫戈,蘋果建議我們使用 Core Foundation 及以上層的 API 進行編程。

socket調(diào)用庫函數(shù)主要有:

創(chuàng)建套接字
Socket(af,type,protocol)

建立地址和套接字的聯(lián)系
bind(sockid, local addr, addrlen)

服務(wù)器端偵聽客戶端的請求
listen( Sockid ,quenlen)

建立服務(wù)器/客戶端的連接 (面向連接TCP)

客戶端請求連接:
Connect(sockid, destaddr, addrlen)

服務(wù)器端等待從編號為Sockid的Socket上接收客戶連接請求
newsockid=accept(Sockid酌壕,Clientaddr, paddrlen)

發(fā)送/接收數(shù)據(jù)

面向連接:
send(sockid, buff, bufflen)       
recv( )

面向無連接:
sendto(sockid,buff,…,addrlen)       
recvfrom( )

釋放套接字:
close(sockid)

socket(套接字)是通信的基石掏愁,是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元歇由,包含進行網(wǎng)絡(luò)通信必須的五種信息:連接使用的協(xié)議,本地主機的IP地址果港,本地進程的協(xié)議端口沦泌,遠(yuǎn)地主機的IP地址,遠(yuǎn)地進程的協(xié)議端口辛掠。

多個TCP連接或多個應(yīng)用程序進程可能需要通過同一個TCP協(xié)議端口傳輸數(shù)據(jù)谢谦。為了區(qū)別不同的應(yīng)用程序進程和連接,計算機操作系統(tǒng)為應(yīng)用程序與TCP/IP協(xié)議交互提供了套接字(Socket)接口萝衩。應(yīng)用層可以和傳輸層通過Socket接口回挽,區(qū)分來自不同應(yīng)用程序進程或網(wǎng)絡(luò)連接的通信,實現(xiàn)數(shù)據(jù)傳輸?shù)牟l(fā)服務(wù)猩谊。

建立Socket連接至少需要一對套接字千劈,其中一個運行于客戶端,稱為ClientSocket牌捷,另一個運行于服務(wù)器端墙牌,稱為ServerSocket。套接字之間的連接過程分為三個步驟:服務(wù)器監(jiān)聽暗甥,客戶端請求喜滨,連接確認(rèn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末撤防,一起剝皮案震驚了整個濱河市虽风,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌寄月,老刑警劉巖辜膝,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異漾肮,居然都是意外死亡内舟,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門初橘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人充岛,你說我怎么就攤上這事保檐。” “怎么了崔梗?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵夜只,是天一觀的道長。 經(jīng)常有香客問我蒜魄,道長扔亥,這世上最難降的妖魔是什么场躯? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮旅挤,結(jié)果婚禮上踢关,老公的妹妹穿的比我還像新娘。我一直安慰自己粘茄,他們只是感情好签舞,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著柒瓣,像睡著了一般儒搭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芙贫,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天搂鲫,我揣著相機與錄音,去河邊找鬼磺平。 笑死魂仍,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的褪秀。 我是一名探鬼主播蓄诽,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼媒吗!你這毒婦竟也來了仑氛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤闸英,失蹤者是張志新(化名)和其女友劉穎锯岖,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體甫何,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡出吹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了辙喂。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捶牢。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖巍耗,靈堂內(nèi)的尸體忽然破棺而出秋麸,到底是詐尸還是另有隱情,我是刑警寧澤炬太,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布灸蟆,位于F島的核電站,受9級特大地震影響亲族,放射性物質(zhì)發(fā)生泄漏炒考。R本人自食惡果不足惜可缚,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望斋枢。 院中可真熱鬧帘靡,春花似錦、人聲如沸杏慰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缘滥。三九已至轰胁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間朝扼,已是汗流浹背赃阀。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留擎颖,地道東北人榛斯。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像搂捧,于是被迫代替她去往敵國和親驮俗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

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