错误描述
- 环境:AsyncSocket客户端建立TCP连接
- 情景1:在网络连接正常情况下,启动应用程序,对socket的连接、断开、重连等操作都没有问题;
- 情景2:在网络异常情况下启动应用程序然后恢复网络,或后台切换网路时,socket无法正常通信,显示连接成功,但是紧接着doCFReadStreamCallback回调中报错,然后就closeWithError
- domain=kCFStreamErrorDomainPOSIX, error=57
一:网上查阅在release情况下指针释放问题,修改如下(并没有解决问题)
static void MyCFReadStreamCallback (CFReadStreamRef stream, CFStreamEventType type, void *pInfo)
{
@autoreleasepool {
AsyncSocket *theSocket =[[AsyncSocket alloc]init];
theSocket = (__bridge AsyncSocket *)pInfo;
[theSocket doCFReadStreamCallback:type forStream:stream];
}
}
�二.判断各种网络情况再选择重新连接(实测解决问题)
-
1.先检查有没有在onSocket:willDisconnectWithError:中去重新创建socket并连接,如果有要去掉,正确应该在- (void)onSocketDidDisconnect:(AsyncSocket *)sock中重新连接,否则会造成closeWithError运行报错
- 注意调用顺序onSocket:willDisconnectWithError:->onSocketDidDisconnect:
2.根据网络状况判断是否进行重连
3.此处没有贴心跳包的代码,如果需要自行添加.
typedef enum SocketStatus{
SocketOfflineByServer,
SocketOfflineByUser,
SocketOfflineByWifiCut,
}_SocketStatus;
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
//对收到的数据进行校验&分析&处理
NSDictionary *infoDic=[NSJSONSerialization JSONObjectWithData:sock.unreadData options:NSJSONReadingAllowFragments error:nil];
NSLog(@"Socket发送失败 json=%@",infoDic);
if (err.code == 57) {
self.socket.userData = SocketOfflineByWifiCut;
}
}
- (void)onSocketDidDisconnect:(AsyncSocket *)sock
{
NSLog(@"断开连接,释放socket");
if (sock.userData == SocketOfflineByServer) {
// 服务器掉线,重连
self.pushCount = 0;
[self reconnectServer];
}
else if (sock.userData == SocketOfflineByUser) {
// 如果由用户断开,不进行重连
return;
}else if (sock.userData == SocketOfflineByWifiCut) {
// wifi断开,不进行重连
return;
}
}
- (void)cutOffScoket
{
self.socket.userData = SocketOfflineByUser;
NSLog(@"断开连接");
if (self.socket!=nil) {
[self.socket disconnect];
[self.socket setDelegate:nil];
self.socket = nil;
}
}
- (void)reconnectServer{
if (_socket!=nil) {
[_socket disconnect];
[_socket setDelegate:nil];
_socket = nil;
}
self.socket = nil;
self.socket = [[AsyncSocket alloc] initWithDelegate:self];
NSError *error = nil;
//重新连接
[self.socket connectToHost:SocketHOST onPort:SokcetPORT error:&error];
if (error) {
NSLog(@"SocketAgainTryConnectError:%@",error);
}
}
- (void)connectToServer
{
self.socket = [[AsyncSocket alloc] initWithDelegate:self];
self.socket.userData = SocketOfflineByServer;
NSError *error = nil;
//开始连接
[self.socket connectToHost:SocketHOST onPort:SocketPORT error:&error];
NSLog(@"tryConnect....");
if (error) {
NSLog(@"error=%@",error);
}
}