關於 iOS socket 都在這裡了

來源:互聯網
上載者:User

標籤:

socket(通訊端)是通訊的基石,是支援TCP/IP協議的網路通訊的基本操作單元,包含進行網路通訊必須的五種資訊:串連使用的協議,本地主機的IP地址,本地進程的協議連接埠,遠地主機的IP地址,遠地進程的協議連接埠。

 

多個TCP串連或多個應用程式進程可能需要通過同一個TCP協議連接埠傳輸資料。為了區別不同的應用程式進程和串連,電腦作業系統為應用程式與TCP/IP協議互動提供了通訊端(Socket)介面。應用程式層可以和傳輸層通過Socket介面,區分來自不同應用程式進程或網路連接的通訊,實現資料轉送的並發服務。

 

建立Socket串連至少需要一對通訊端,其中一個運行於用戶端,稱為ClientSocket,另一個運行於伺服器端,稱為ServerSocket。通訊端之間的串連過程分為三個步驟:伺服器監聽,用戶端請求,串連確認。

 

Socket可以支援不同的傳輸層協議(TCP或UDP),當使用TCP協議進行串連時,該Socket串連就是一個TCP串連,UDP串連同理。

 

 

socket使用的庫函數

 

1.建立通訊端

 

Socket(af,type,protocol)//建立地址和通訊端的聯絡

 

bind(sockid, local addr, addrlen)//伺服器端偵聽用戶端的請求

 

listen( Sockid ,quenlen)//建立伺服器/用戶端的串連 (連線導向TCP)

 

2.用戶端請求串連

 

Connect(sockid, destaddr, addrlen)//伺服器端等待從編號為Sockid的Socket上接收客戶串連請求

 

newsockid=accept(Sockid,Clientaddr, paddrlen)//發送/接收資料

 

3.連線導向:

 

send(sockid, buff, bufflen)

recv( )

 

4.面向無串連:

 

sendto(sockid,buff,…,addrlen)

recvfrom( )

 

5.釋放通訊端

 

close(socked)

 

在iOS中以NSStream(流)來發送和接收資料,可以設定流的代理,對流狀態的變化做出相應的動作(串連建立,接收到資料,串連關閉)。

 

NSStream:資料流的父類,用於定義抽象特性,例如:開啟、關閉代理,NSStream繼承自CFStream(CoreFoundation)

NSInputStream:NSStream的子類,用於讀取輸入

NSOutputStream:NSSTream的子類,用於寫輸出。

 

服務端先不提,用戶端代碼大概如下:

 

//需要匯入<arpa/inet.h>,<netdb.h>

- (void)test

{

NSString * host =@"123.33.33.1";

NSNumber * port = @1233;

 

// 建立 socket

int socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0);

if (-1 == socketFileDescriptor) {

    NSLog(@"建立失敗");

    return;

}

 

// 擷取 IP 位址

struct hostent * remoteHostEnt = gethostbyname([host UTF8String]);

if (NULL == remoteHostEnt) {

    close(socketFileDescriptor);

     NSLog(@"%@",@"無法解析伺服器的主機名稱");

    return;

}

 

struct in_addr * remoteInAddr = (struct in_addr *)remoteHostEnt->h_addr_list[0];

 

// 設定 socket 參數

struct sockaddr_in socketParameters;

socketParameters.sin_family = AF_INET;

socketParameters.sin_addr = *remoteInAddr;

socketParameters.sin_port = htons([port intValue]);

 

// 串連 socket

int ret = connect(socketFileDescriptor, (struct sockaddr *) &socketParameters, sizeof(socketParameters));

if (-1 == ret) {

    close(socketFileDescriptor);

    NSLog(@"串連失敗");

    return;

}

 

NSLog(@"串連成功");

}

 

大概就是這樣,因為是C語言的,所以看起來不是很方便,一般開發中都會使用比較簡單的方法,如下。

 

CocoaAsyncSocket

 

iOS的socket實現是特別簡單的,可以使用用github的開源類庫cocoaasyncsocket簡化開發,cocoaasyncsocket是支援tcp和ump的。代碼大概如下:

 

- (IBAction)connectToServer:(id)sender {

// 1.與伺服器通過三向交握建立串連

NSString *host = @"133.33.33.1";

int port = 1212;

 

//建立一個socket對象

_socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];

 

//串連

NSError *error = nil;

[_socket connectToHost:host onPort:port error:&error];

 

if (error) {

    NSLog(@"%@",error);

}

}

 

 

#pragma mark -socket的代理

#pragma mark 串連成功

-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{

NSLog(@"%s",__func__);

}

 

 

#pragma mark 中斷連線

-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{

if (err) {

    NSLog(@"串連失敗");

}else{

    NSLog(@"正常斷開");

}

}

 

 

#pragma mark 資料發送成功

-(void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{

NSLog(@"%s",__func__);

 

//發送完資料手動讀取,-1不設定逾時

[sock readDataWithTimeout:-1 tag:tag];

}

 

#pragma mark 讀取資料

-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{

NSString *receiverStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSLog(@"%s %@",__func__,receiverStr);

}

 

下面是原理補充,有興趣的朋友可以細看。

 

 

網路七層協議

 

網路七層協議由下往上分別為物理層、資料連結層、網路層、傳輸層、會話層、展示層和應用程式層。其中物理層、資料連結層和網路層通常被稱作媒體層,是網路工程師所研究的對象;傳輸層、會話層、展示層和應用程式層則被稱作主機層,是使用者所面向和關心的內容。

 

HTTP協議對應於應用程式層,TCP協議對應於傳輸層,IP協議對應於網路層,HTTP協議是基於TCP串連的,三者本質上沒有可比性。 TCP/IP是傳輸層協議,主要解決資料如何在網路中傳輸;而HTTP是應用程式層協議,主要解決如何封裝資料。Socket是應用程式層與TCP/IP協議族通訊的中間軟體抽象層,是它的一組介面。

 

網路七層協議

 

TCP/IP五層模型

 

TCP/IP五層模型的協議分為:應用程式層、傳輸層、網路層、資料連結層和物理層。中繼器、集線器、還有我們通常說的雙絞線也工作在物理層;橋接器(現已很少使用)、乙太網路交換器(二層交換器)、網卡(其實網卡是一半工作在物理層、一半工作在資料連結層)在資料連結層;路由器、三層交換器在網路層;傳輸層主要是四層交換器、也有工作在四層的路由器。

 

TCP/IP協議中的應用程式層處理七層模型中的第五層、第六層和第七層的功能。TCP/IP協議中的傳輸層並不能總是保證在傳輸層可靠地傳輸資料包,而七層模型可以做到。TCP/IP協議還提供一項名為UDP(使用者資料包通訊協定)的選擇。UDP不能保證可靠的資料包傳輸。

 

對應關係

 

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

UDP:面向非串連、傳輸不可靠、用於傳輸少量資料(資料包模式)、速度快。

TCP是一種流模式的協議,UDP是一種資料報模式的協議。

在傳輸資料時,可以只使用傳輸層(TCP/IP),但是那樣的話,由於沒有應用程式層,便無法識別資料內容,如果想要使傳輸的資料有意義,則必須使用應用程式層協議(HTTP、FTP、TELNET等),也可以自己定義應用程式層協議。

 

WEB使用HTTP作傳輸層協議,以封裝HTTP文本資訊,然後使用TCP/IP做傳輸層協議將它發送到網路上。Socket是對TCP/IP協議的封裝,Socket本身並不是協議,而是一個調用介面(API),通過Socket,我們才能使用TCP/IP協議。

 

Socket的位置

 

TCP串連

 

要想明白Socket串連,先要明白TCP串連。手機能夠使用連網功能是因為手機底層實現了TCP/IP協議,可以使手機終端通過無線網路建立TCP串連。TCP協議可以對上層網路提供介面,使上層網路資料的傳輸建立在“無差別”的網路之上。

 

建立起一個TCP串連需要經過“三向交握”:

第一次握手:用戶端發送syn包(syn=j)到伺服器,並進入SYN_SEND狀態,等待伺服器確認;

第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;

第三向交握:用戶端收到伺服器的SYN+ACK包,向伺服器發送確認包ACK(ack=k+1),此包發送完畢,用戶端和伺服器進入ESTABLISHED狀態,完成三向交握。

 

三向交握(Three-way Handshake)即建立一個TCP串連時,需要用戶端和伺服器總共發送3個包。三向交握的目的是串連伺服器指定連接埠,建立TCP串連,並同步串連雙方的序號和確認號並交換TCP 視窗大小資訊。在socket編程中,用戶端執行connect()時,將觸發三向交握。

 

三向交握

 

握手過程中傳送的包裡不包含資料,三向交握完畢後,用戶端與伺服器才正式開始傳送資料。理想狀態下,TCP串連一旦建立,在通訊雙方中的任何一方主動關閉串連之前,TCP 串連都將被一直保持下去。中斷連線時伺服器和用戶端均可以主動發起斷開TCP串連的請求,斷開過程需要經過“四次握手”。

 

TCP串連的拆除需要發送四個包,因此稱為四次握手(four-way handshake)。在socket編程中,任何一方執行close()操作即可產生握手(有地方稱為“揮手”)操作。

 

TCP串連的拆除

 

之所以有“三向交握”和“四次握手”的區別,是因為串連時當Server端收到Client端的SYN串連請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉串連時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回複一個ACK報文,告訴Client端,”你發的FIN報文我收到了”。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。

 

HTTP串連

 

HTTP協議即超文本傳送協議(HypertextTransfer Protocol ),是Web連網的基礎,也是手機連網常用的協議之一,HTTP協議是建立在TCP協議之上的一種應用。

 

HTTP串連最顯著的特點是用戶端發送的每次請求都需要伺服器回送響應,在請求結束後,會主動釋放串連。從建立串連到關閉串連的過程稱為“一次串連”。因此HTTP串連是一種“短串連”,要保持用戶端程式的線上狀態,需要不斷地向伺服器發起串連請求。若伺服器長時間無法收到用戶端的請求,則認為用戶端“下線”,若用戶端長時間無法收到伺服器的回複,則認為網路已經斷開。在HTTP 1.0中,用戶端的每次請求都要求建立一次單獨的串連,在處理完本次請求後,就自動釋放串連。在HTTP 1.1中則可以在一次串連中處理多個請求,並且多個請求可以重疊進行,不需要等待一個請求結束後再發送下一個請求。

 

HTTPS(Hyper Text Transfer Protocol over Secure Socket Layer),是以安全為目標的HTTP通道,是HTTP的安全版。 在HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。 HTTPS存在不同於HTTP的預設連接埠及一個加密/身分識別驗證層(在HTTP與TCP之間)。HTTP協議以明文方式發送內容,不提供任何方式的資料加密,如果攻擊者截取了Web瀏覽器和網站伺服器之間的傳輸報文,就可以直接讀懂其中的資訊,因此HTTP協議不適合傳輸一些敏感資訊。

 

https協議需要到ca申請認證;http是超文字傳輸通訊協定 (HTTP),資訊是明文傳輸,https 則是具有安全性的ssl加密傳輸協議;http和https使用的是完全不同的串連方式,用的連接埠也不一樣,前者是80,後者是443;http的串連很簡單,是無狀態的,HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網路通訊協定。

 

HTTPS

 

Socket串連與HTTP串連的不同

 

通常情況下Socket串連就是TCP串連,因此Socket串連一旦建立,通訊雙方即可開始相互發送資料內容,直到雙方串連斷開。但在實際應用中,用戶端到伺服器之間的通訊防火牆預設會關閉長時間處於非活躍狀態的串連而導致 Socket 串連斷連,因此需要通過輪詢告訴網路,該串連處於活躍狀態。

 

而HTTP串連使用的是“請求—響應”的方式,不僅在請求時需要先建立串連,而且需要用戶端向伺服器發出請求後,伺服器端才能回複資料。

關於 iOS socket 都在這裡了

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.