CocoaAsyncSocket为macOS、iOS和tvOS提供了易于使用且功能强大的异步套接字库。他是基于C 语言Socket的一层封装,更加的面向对象。使得原生连接状态以及接受消息等函数都以代理的方式体现。使用性极高,极大提高开发效率。
CocoaAsyncSocket中主要包含两个类:
@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;
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);
}