iOS開發 Socket網絡編程

1.Socket簡介

首先讓我們通過一張圖知道socket在哪里?

socket在哪里

Socket是應用層與TCP/IP協議族通信的中間軟件抽象層,它是一組接口。

2.TCP和UDP的區別

在這里就必須講一下udp和tcp的區別了

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

UDP:面向非連接、傳輸不可靠、用于傳輸少量數據(數據包模式)、速度快。

關于TCP是一種流模式的協議,UDP是一種數據報模式的協議,這里要說明一 下,TCP是面向連接的,也就是說,在連接持續的過程中,socket中收到的數據都是由同一臺主機發出的(劫持什么的不考慮),因此,知道保證數據是有 序的到達就行了,至于每次讀取多少數據自己看著辦。

而UDP是無連接的協議,也就是說,只要知道接收端的IP和端口,且網絡是可達的,任何主機都可以向接收端發送數據。這時候,如果一次能讀取超過一 個報文的數據,則會亂套。比如,主機A向發送了報文P1,主機B發送了報文P2,如果能夠讀取超過一個報文的數據,那么就會將P1和P2的數據合并在了一 起,這樣的數據是沒有意義的。

3.TCP三次握手和四次揮手

相對于SOCKET開發者,TCP創建過程和連接拆除過程是由TCP/IP協議棧自動創建的。因此開發者并不需要控制這個過程。但是對于理解TCP底層運作機制,相當有幫助。

因此在這里詳細解釋一下這兩個過程。

TCP三次握手

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

三次握手的目的是連接服務器指定端口,建立TCP連接,并同步連接雙方的序列號和確認號并交換 TCP 窗口大小信息.在socket編程中,客戶端執行connect()時。將觸發三次握手


TCP三次握手

首先了解一下幾個標志,SYN(synchronous),同步標志,ACK (Acknowledgement),即確認標志,seq應該是Sequence Number,序列號的意思,另外還有四次握手的fin,應該是final,表示結束標志。

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

第二次握手:服務器發回確認包(ACK)應答。即SYN標志位和ACK標志位均為1同時,將確認序號(Acknowledgement Number)設置為客戶的序列號加1以,即X+1。

第三次握手:客戶端再次發送確認包(ACK) SYN標志位為0,ACK標志位為1。并且把服務器發來ACK的序號字段+1,放在確定字段中發送給對方.并且在數據段放寫序列號的+1。

TCP四次揮手

TCP的連接的拆除需要發送四個包,因此稱為四次揮手(four-way handshake)??蛻舳嘶蚍掌骶芍鲃影l起揮手動作,在socket編程中,任何一方執行close()操作即可產生揮手操作。

TCP四次揮手

其實有個問題,為什么連接的時候是三次握手,關閉的時候卻是四次揮手?

因為當Server端收到Client端的SYN連接請求報文后,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來 同步的。但是關閉連接時,當Server端收到FIN報文時,很可能并不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端," 你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。

TCPsocket和UDPsocket的具體實現

講了這么久,終于要開始講socket的具體實現了,iOS提供了Socket網絡編程的接口CFSocket,不過這里使用BSD Socket。

tcp和udp的socket是有區別的,這里給出這兩種的設計框架

基本TCP客戶—服務器程序設計基本框架

基本TCP客戶—服務器程序設計基本框架

基本UDP客戶—服務器程序設計基本框架流程圖

基本UDP客戶—服務器程序設計基本框架流程圖

常用的Socket類型有兩種:流式Socket(SOCK_STREAM) 和數據報式Socket(SOCK_DGRAM)。流式是一種面向連接的Socket,針對于面向連接的TCP服務應用;數據報式Socket是一種無連 接的Socket,對應于無連接的UDP服務應用。

1、socket調用庫函數主要有:

創建套接字?

1

????????

Socket(af,type,protocol)

建立地址和套接字的聯系?

1

????????

bind(sockid,?local?addr,?addrlen)

服務器端偵聽客戶端的請求?

1

????????

listen(?Sockid?,quenlen)

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

??????? 客戶端請求連接?

1

????????

Connect(sockid,?destaddr,?addrlen)

??????? 服務器端等待從編號為Sockid的Socket上接收客戶連接請求?

1

????????

newsockid=accept(Sockid,Clientaddr,?paddrlen)

發送/接收數據?

??????? 面向連接:

1

2

????????

send(sockid,?buff,?bufflen)?

????????

recv(?)

??????? 面向無連接:

1

2

????????

sendto(sockid,buff,…,addrlen)?

????????

recvfrom(?)

釋放套接字?

1??????? close(sockid)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容