Socket是應(yīng)用層與TCP/IP協(xié)議族通信的中間軟件抽象層溪猿,它是一組接口刃跛。 TCP和UDP的區(qū)別
TCP:面向連接抠艾、傳輸可靠(保證數(shù)據(jù)正確性、保證數(shù)據(jù)順序)桨昙、用于傳輸大量數(shù)據(jù)(流模式)检号、速度慢,建立連接需要開(kāi)銷較多(時(shí)間绊率,系統(tǒng)資源)谨敛。
UDP:面向非連接、傳輸不可靠滤否、用于傳輸少量數(shù)據(jù)(數(shù)據(jù)包模式)脸狸、速度快。
關(guān)于TCP是一種流模式的協(xié)議藐俺,UDP是一種數(shù)據(jù)報(bào)模式的協(xié)議炊甲,這里要說(shuō)明一下,TCP是面向連接的欲芹,也就是說(shuō)卿啡,在連接持續(xù)的過(guò)程中,socket中收到的數(shù)據(jù)都是由同一臺(tái)主機(jī)發(fā)出的(劫持什么的不考慮)菱父,因此颈娜,知道保證數(shù)據(jù)是有序的到達(dá)就行了,至于每次讀取多少數(shù)據(jù)自己看著辦浙宜。
而UDP是無(wú)連接的協(xié)議官辽,也就是說(shuō),只要知道接收端的IP和端口粟瞬,且網(wǎng)絡(luò)是可達(dá)的同仆,任何主機(jī)都可以向接收端發(fā)送數(shù)據(jù)问慎。這時(shí)候盐类,如果一次能讀取超過(guò)一個(gè)報(bào)文的數(shù)據(jù),則會(huì)亂套秘蛔。比如市怎,主機(jī)A向發(fā)送了報(bào)文P1岁忘,主機(jī)B發(fā)送了報(bào)文P2,如果能夠讀取超過(guò)一個(gè)報(bào)文的數(shù)據(jù)区匠,那么就會(huì)將P1和P2的數(shù)據(jù)合并在了一起臭觉,這樣的數(shù)據(jù)是沒(méi)有意義的。 TCP三次握手和四次揮手
相對(duì)于socket開(kāi)發(fā)者,TCP創(chuàng)建過(guò)程和連接拆除過(guò)程是由TCP/IP協(xié)議棧自動(dòng)創(chuàng)建的蝠筑。因此開(kāi)發(fā)者并不需要控制這個(gè)過(guò)程狞膘。但是對(duì)于理解TCP底層運(yùn)作機(jī)制,相當(dāng)有幫助什乙。
因此在這里詳細(xì)解釋一下這兩個(gè)過(guò)程挽封。 TCP三次握手
所謂三次握手(Three-way Handshake),是指建立一個(gè)TCP連接時(shí)臣镣,需要客戶端和服務(wù)器總共發(fā)送3個(gè)包辅愿。
三次握手的目的是連接服務(wù)器指定端口,建立TCP連接,并同步連接雙方的序列號(hào)和確認(rèn)號(hào)并交換 TCP 窗口大小信息.在socket編程中忆某,客戶端執(zhí)行connect()時(shí)点待。將觸發(fā)三次握手。
TCP 三次握手
首先了解一下幾個(gè)標(biāo)志弃舒,SYN(synchronous)癞埠,同步標(biāo)志,ACK (Acknowledgement)聋呢,即確認(rèn)標(biāo)志苗踪,seq應(yīng)該是Sequence Number,序列號(hào)的意思削锰,另外還有四次握手的fin通铲,應(yīng)該是final,表示結(jié)束標(biāo)志器贩。
第一次握手:客戶端發(fā)送一個(gè)TCP的SYN標(biāo)志位置1的包指明客戶打算連接的服務(wù)器的端口颅夺,以及初始序號(hào)X,保存在包頭的序列號(hào)(Sequence Number)字段里。
第二次握手:服務(wù)器發(fā)回確認(rèn)包(ACK)應(yīng)答蛹稍。即SYN標(biāo)志位和ACK標(biāo)志位均為1同時(shí)吧黄,將確認(rèn)序號(hào)(Acknowledgement Number)設(shè)置為客戶的序列號(hào)加1以,即X+1稳摄。
第三次握手:客戶端再次發(fā)送確認(rèn)包(ACK) SYN標(biāo)志位為0,ACK標(biāo)志位為1饲宿。并且把服務(wù)器發(fā)來(lái)ACK的序號(hào)字段+1厦酬,放在確定字段中發(fā)送給對(duì)方.并且在數(shù)據(jù)段放寫(xiě)序列號(hào)的+1。 TCP四次揮手
TCP的連接的拆除需要發(fā)送四個(gè)包瘫想,因此稱為四次揮手(four-way handshake)仗阅。客戶端或服務(wù)器均可主動(dòng)發(fā)起揮手動(dòng)作国夜,在socket編程中减噪,任何一方執(zhí)行close()操作即可產(chǎn)生揮手操作。
TCP 四次揮手
其實(shí)有個(gè)問(wèn)題,為什么連接的時(shí)候是三次握手筹裕,關(guān)閉的時(shí)候卻是四次揮手醋闭?
因?yàn)楫?dāng)Server端收到Client端的SYN連接請(qǐng)求報(bào)文后,可以直接發(fā)送SYN+ACK報(bào)文朝卒。其中ACK報(bào)文是用來(lái)應(yīng)答的证逻,SYN報(bào)文是用來(lái)同步的。但是關(guān)閉連接時(shí)抗斤,當(dāng)Server端收到FIN報(bào)文時(shí)囚企,很可能并不會(huì)立即關(guān)閉socket,所以只能先回復(fù)一個(gè)ACK報(bào)文瑞眼,告訴Client端龙宏,”你發(fā)的FIN報(bào)文我收到了”。只有等到我Server端所有的報(bào)文都發(fā)送完了伤疙,我才能發(fā)送FIN報(bào)文银酗,因此不能一起發(fā)送。故需要四步握手掩浙。 TCPSocket和UDPSocket的具體實(shí)現(xiàn)
講了這么久花吟,終于要開(kāi)始講socket的具體實(shí)現(xiàn)了,iOS提供了socket網(wǎng)絡(luò)編程的接口CFSocket厨姚,不過(guò)這里使用BSD Socket衅澈。
TCP和UDP的socket是有區(qū)別的,這里給出這兩種的設(shè)計(jì)框架
TCP客戶—服務(wù)器程序設(shè)計(jì)基本框架
UDP客戶—服務(wù)器程序設(shè)計(jì)基本框架流程圖
常用的socket類型有兩種:流式socket(SOCK_STREAM)和數(shù)據(jù)報(bào)式socket(SOCK_DGRAM)谬墙。流式是一種面向連接的socket今布,針對(duì)于面向連接的TCP服務(wù)應(yīng)用;數(shù)據(jù)報(bào)式socket是一種無(wú)連接的socket拭抬,對(duì)應(yīng)于無(wú)連接的UDP服務(wù)應(yīng)用部默。 TCPSocket的具體實(shí)現(xiàn)
服務(wù)器的工作流程:首先調(diào)用socket函數(shù)創(chuàng)建一個(gè)Socket,然后調(diào)用bind函數(shù)將其與本機(jī)地址以及一個(gè)本地端口號(hào)綁定造虎,然后調(diào)用listen在相應(yīng)的socket上監(jiān)聽(tīng)傅蹂,當(dāng)accpet接收到一個(gè)連接服務(wù)請(qǐng)求時(shí),將生成一個(gè)新的socket算凿。服務(wù)器顯示該客戶機(jī)的IP地址份蝴,并通過(guò)新的socket向客戶端發(fā)送字符串” hi,I am server!”。最后關(guān)閉該socket氓轰。
客戶端的工作流程:首先調(diào)用socket函數(shù)創(chuàng)建一個(gè)Socket婚夫,然后調(diào)用bind函數(shù)將其與本機(jī)地址以及一個(gè)本地端口號(hào)綁定,請(qǐng)求連接服務(wù)器署鸡,通過(guò)新的socket向客戶端發(fā)送字符串” hi,I am client!”案糙。最后關(guān)閉該socket限嫌。 UDPSocket的具體實(shí)現(xiàn)
服務(wù)器的工作流程:首先調(diào)用socket函數(shù)創(chuàng)建一個(gè)Socket,然后調(diào)用bind函數(shù)將其與本機(jī)地址以及一個(gè)本地端口號(hào)綁定时捌,接收到一個(gè)客戶端時(shí)怒医,服務(wù)器顯示該客戶端的IP地址,并將字串返回給客戶端匣椰。
客戶端的工作流程:首先調(diào)用socket函數(shù)創(chuàng)建一個(gè)Socket裆熙,填寫(xiě)服務(wù)器地址及端口號(hào),從標(biāo)準(zhǔn)輸入設(shè)備中取得字符串禽笑,將字符串傳送給服務(wù)器端入录,并接收服務(wù)器端返回的字符串。最后關(guān)閉該socket佳镜。