這篇文章只是簡單記錄下GCDAsyncSocket用戶端的簡單用法,后續(xù)我會把os層基于C的 BSD socket,Core Foundation層的CFNetWork以及cocoa層的NSStream簡單用法整理出來,以備今后查詢.各位大神如果有深入的研究的或者有什么好的使用技巧了都可以交流下哦,歡迎指出使用不當之處.
Socket
- 網(wǎng)絡上的兩個程序通過一個雙向的通信連接實現(xiàn)數(shù)據(jù)的交換砂心,這個連接的一端稱為一個socket
- socket又稱"套接字", 應用程序通過"套接字"向網(wǎng)絡發(fā)出請求或者應答網(wǎng)絡請求.
- socket常用的網(wǎng)絡請求TCP和UDP
根據(jù)連接啟動的方式以及本地套接字要連接的目標,套接字之間的連接過程可以分為三個步驟:服務器監(jiān)聽,客戶端請求,連接確認间狂。
(1)服務器監(jiān)聽:是服務器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態(tài),實時監(jiān)控網(wǎng)絡狀態(tài).
(2)客戶端請求:是指由客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字.為此,客戶端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然后就向服務器端套接字提出連接請求.
(3)連接確認:是指當服務器端套接字監(jiān)聽到或者說接收到客戶端套接字的連接請求,它就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述發(fā)給客戶端,一旦客戶端確認了此描述,連接就建立好了.而服務器端套接字繼續(xù)處于監(jiān)聽狀態(tài),繼續(xù)接收其他客戶端套接字的連接請求. - Socket的通信流程圖
Snip20160707_1.png
GCDAsyncSocket用法
-創(chuàng)建Socket對象.GCDAsyncSocket中socket鏈接后的事件處理都是在代理里面的
// 創(chuàng)建Socket對象
// 設置代理,讓代理在全局隊列中調(diào)用
GCDAsyncSocket *clientSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
// 用強指針引用著Socket對象
self.clientSocket = clientSocket;
NSString *host = nil;
uint16_t port = 8288;
// 連接服務器
NSError *error = nil;
[clientSocket connectToHost:host onPort:port error:&error];
if (error) {
NSLog(@"%@", error.localizedDescription);
}
- 常用的幾個代理,GCDAsyncSocketDelegate.注意:在鏈接成功之后要監(jiān)聽數(shù)據(jù)的讀取,接收到數(shù)據(jù)后也要監(jiān)聽數(shù)據(jù)的讀取,接收數(shù)據(jù)的代理不會被回調(diào).
// 連接成功后的回調(diào)
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
// 監(jiān)聽讀取數(shù)據(jù)
[sock readDataWithTimeout:-1 tag:0];
}
// 與服務器斷開連接后的回調(diào)
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
// 可以調(diào)用該方法查看斷開連接的原因
NSLog(@"%@", err);
}
// 接收數(shù)據(jù)的回調(diào)
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
// 接收到的消息
NSString *messageStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", messageStr);
// 準備讀取下次的數(shù)據(jù)
[sock readDataWithTimeout:-1 tag:0];
}
- 發(fā)送消息
/**
* 發(fā)送消息
*
* @param sendMessage 發(fā)送的消息內(nèi)容
*/
- (void)sendMessage:(NSString *)sendMessage{
if (sendMessage == nil || sendMessage.length == 0) {
return;
}
// 發(fā)送
[self.clientSocket writeData:[sendMessage dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:0];
}
// 發(fā)送消息成功后的回調(diào),消息發(fā)送成功后可以在這個代理里面做一些處理
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
}