CocoaAsyncSocket爲macOS、iOS和tvOS提供了易於使用且功能強大的異步套接字庫。他是基於C 語言Socket的一層封裝,更加的面向對象。使得原生連接狀態以及接受消息等函數都以代理的方式體現。使用性極高,極大提高開發效率。
CocoaAsyncSocket中主要包含兩個類:
- GCDAsyncSocket.//基於TCP/IP協議的socket網絡庫
- GCDAsyncUdpSocket.//基於UDP/IP協議的socket網絡庫
GCDAsyncSocket 的使用
@property (nonatomic, strong) GCDAsyncSocket *socket;
// 1: 創建socekt --id -->
if (self.socket == nil) {
self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
}
// 2: 連接socket
if (!self.socket.isConnected) {
NSError *error;
[self.socket connectToHost:@"127.0.0.1" onPort:8090 error:&error];
}
// 發送消息
NSData *data = [self.contentTF.text dataUsingEncoding:NSUTF8StringEncoding];
[self.socket writeData:data withTimeout:-1 tag:10086];
GCDAsyncSocketDelegate
//已經連接到服務器
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(nonnull NSString *)host port:(uint16_t)port{
NSLog(@"連接成功 : %@---%d",host,port);
[self.socket readDataWithTimeout:-1 tag:10086];
}
// 連接斷開
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
NSLog(@"斷開 socket連接 原因:%@",err);
}
//已經接收服務器返回來的數據
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
NSLog(@"接收到tag = %ld : %ld 長度的數據",tag,data.length);
[self.socket readDataWithTimeout:-1 tag:10086];
// 每次發送數據必須重新開啓監聽,(經典問題)
}
//消息發送成功 代理函數 向服務器 發送消息
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{
NSLog(@"%ld 發送數據成功",tag);
}
重連和斷開的操作
//重新連接
// 1: 創建socekt --id -->
if (self.socket == nil) {
self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
}
// 2: 連接socket
if (!self.socket.isConnected) {
NSError *error;
[self.socket connectToHost:@"127.0.0.1" onPort:8090 error:&error];
}
//關閉socket
[self.socket disconnect];
self.socket = nil;
GCDAsyncUdpSocket
udp 在連接的時候直接綁定端口,不需要地址的連接,極大節約了時間。 在發送消息的時候,直接對着某個地址的的某個端口直接發送,類似廣播形式。
@property (nonatomic, strong) GCDAsyncUdpSocket *udpSocket;
// 1. 創建UDP
if (!self.udpSocket) {
self.udpSocket = [[GCDAsyncUdpSocket alloc]initWithDelegate:sender delegateQueue:dispatch_get_global_queue(0, 0)];
}
//2. 綁定socket
NSError *error;
[self.udpSocket bindToPort:8090 error:&error];
if (error) {
// 監聽錯誤
}else{
//監聽成功則開始接收消息
[self.udpSocket beginReceiving:&error];
}
// 發送消息
[self.udpSocket sendData:[NSData new] toHost:@"192.168.31.19" port:8090 withTimeout:-1 tag:10010];
#pragma mark - GCDAsyncUdpSocketDelegate
// 連接成功
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didConnectToAddress:(NSData *)address{
NSLog(@"連接成功 --- %@",address);
}
// 連接失敗
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotConnect:(NSError *)error{
NSLog(@"連接失敗 反饋: %@",error);
}
// 發送數據成功
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didSendDataWithTag:(long)tag{
NSLog(@"%ld tag 發送數據成功",tag);
}
// 發送數據失敗
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didNotSendDataWithTag:(long)tag dueToError:(NSError *)error{
NSLog(@"%ld tag 發送數據失敗 : %@",tag,error);
}
// 接受數據的回調
- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data fromAddress:(NSData *)address withFilterContext:(id)filterContext{
}
// 關閉失敗
- (void)udpSocketDidClose:(GCDAsyncUdpSocket *)sock withError:(NSError *)error{
NSLog(@"關閉失敗: %@",error);
}