iOS的GCDAsyncSocket快速开发Socket通信
2017-04-06 19:22
330 查看
iOS 基于GCDAsyncSocket快速开发Socket通信
2016年1月17日GCDAsyncSocket是CocoaAsyncSocket第三方库中的其中一个类,本文介绍的就是基于这一个类来做快速的socket通信开发,而且该库已经支持IPv4和IPv6
我们对GCDAsyncSocket做了一层封装调用,它包含了建连、断开、重连、心跳、自定义请求
首先,介绍一下CocoaAsyncSocket第三方库的用途
CocoaAsyncSocket provides easy-to-use and powerful asynchronous socket libraries for Mac and iOS.
翻译成:
CocoaAsyncSocket为Mac和iOS提供了易于使用且强大的异步通信库
在Podfile文件中,只要加上这句话就可以使用了
pod 'CocoaAsyncSocket', '7.4.1' |
下面,我就按照这个四个基本功能来讲一下,怎么来使用CocoaAsyncSocket中GCDAsyncSocket这个类来开发Socket通信
首先,Socket在第一步时,需要建连才能开始通信
在GCDAsyncSocket中提供了四种初始化的方法
- (id)init; - (id)initWithSocketQueue:(dispatch_queue_t)sq; - (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq; - (id)initWithDelegate:(id)aDelegate delegateQueue:(dispatch_queue_t)dq socketQueue:(dispatch_queue_t)sq; @property (atomic, weak, readwrite) id delegate; #if OS_OBJECT_USE_OBJC @property (atomic, strong, readwrite) dispatch_queue_t delegateQueue; #else @property (atomic, assign, readwrite) dispatch_queue_t delegateQueue; #endif |
aDelegate就是socket的代理
dq是delegate的线程
必须要需要设置socket的代理以及代理的线程,否则socket的回调你压根儿就不知道了,
比如:
self.socket =[[GCDAsyncSocket alloc] initWithDelegate:delegate delegateQueue:dispatch_get_main_queue()]; |
- (BOOL)connectToHost:(NSString *)host onPort:(uint16_t)port withTimeout:(NSTimeInterval)timeout error:(NSError **)errPtr; |
如果建连成功之后,会收到socket成功的回调,在成功里面你可以做你需要做的一些事情,我这边的话,是做了心跳的处理
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port; |
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err; |
- (void)socketDidDisconnect:(GCDAsyncSocket*)sock withError:(NSError*)err { self.status= -1; if(self.reconnection_time>=0 && self.reconnection_time <= kMaxReconnection_time) { [self.timer invalidate]; self.timer=nil; int time =pow(2,self.reconnection_time); self.timer= [NSTimer scheduledTimerWithTimeInterval:time target:selfselector:@selector(reconnection) userInfo:nil repeats:NO]; self.reconnection_time++; NSLog(@"socket did reconnection,after %ds try again",time); } else { self.reconnection_time=0; NSLog(@"socketDidDisconnect:%p withError: %@", sock, err); } } |
那么socket已经建连了,该怎么发起socket通信呢?
你需要和后端开发人员商定好socket协议格式,比如:
[NSString stringWithFormat:@"{\"version\":%d,\"reqType\":%d,\"body\":\"%@\"}\r\n",PROTOCOL_VERSION,reqType,reqBody]; |
这个\r\n是socket消息的边界符,是为了防止发生消息黏连,没有\r\n的话,可能由于某种原因,后端会收到两条socket请求,但是后端不知道怎么拆分这两个请求
同理,在收到socket请求回调时,也会根据这个边界符去拆分
那为什么要用\r\n呢?
而且GCDAsyncSocket不支持自定义边界符,它提供了四种边界符供你使用\r\n、\r、\n、空字符串
在拼装好socket请求之后,你需要调用GCDAsyncSocket的写方法,来发送请求,然后在写完成之后你会收到写的回调
[self.socket writeData:requestData withTimeout:-1 tag:0]; |
这个是写的回调
- (void)socket:(GCDAsyncSocket*)sock didWriteDataWithTag:(long)tag; |
[self.socketreadDataToData:[GCDAsyncSocket CRLFData] withTimeout:10 maxLength:50000 tag:0]; |
在读回调里面,你可以根据不同业务来执行不同的操作
- (void)socket:(GCDAsyncSocket*)sock didReadData:(NSData*)data withTag:(long)tag; |
[self.socket disconnect]; |
2016.4.26更新
在网络环境以及其他因素下,很有可能会造成客户端或者后端没有接收到回调或者请求,那该怎么办?
我们需要加上消息回执的处理
客户端发出请求的时候,可以将该请求放到存到数组里面,等到后端的相应回调在移除掉,如果该请求超时或者在一段时间内没有收到确认返回,说明后端没有接收到我们的请求,我们可以将该请求重新发送
客户端接收请求的时候,后端将数据发给客户端,客户端需要增加回执处理,告诉后端,客户端接收到数据了,如果后端没接收到,也重新推一遍数据,客户端和后端双向保护来解决丢失问题
2016.8.5更新
有些时候,不能定位是否是后端问题还是客户端/SDK问题的时候,可以用命令行抓一下socket包看看(用Charles只能抓http和https包)
命令行如下:
sudo tcpdump -i any -n -X port 7070 |
效果如下:
红色部分就是socket包的内容了
相关文章推荐
- iOS 基于GCDAsyncSocket快速开发Socket通信
- iOS 基于GCDAsyncSocket快速开发Socket通信(1)
- 【即时通讯】iOS 基于GCDAsyncSocket快速开发Socket通信
- iOS用GCDAsyncSocket开发Socket通信
- iOS开发——GCDAsyncSocket
- GCDAsyncSocket不通过服务器进行客户端间直接连接—iOS移动开发
- IOS 开发之Cocoa AsyncSocket学习 .
- iOS scoket 再探。换成了GCDAsyncSocket,并且实现了双方聊天
- iOS开发之CocoaAsyncSocket学习
- IOS socket GCDAsyncSocket
- GCDAsyncSocket类库,IOS下TCP通讯使用心得
- 【IOS网络通信】socket第三方库 AsyncSocket(GCDAsyncSocket)
- iOS开发之CocoaAsyncSocket学习
- iOS开发之CocoaAsyncSocket学习
- iOS GCDAsyncSocket
- IOS -- xmppStreamDidDisconnect: Error Domain=GCDAsyncSocketErrorDomain Code=7 解决方案
- iOS开发之CocoaAsyncSocket学习
- 【IOS网络通信】socket第三方库 AsyncSocket(GCDAsyncSocket)
- IOS使用AsyncSocket进行Socket通信
- iOS开发之CocoaAsyncSocket学习