在项目中用到GCDAsyncsocket,Mac端作为服务器,手机端作为客户端,在通信过程中,不定时出现以下错误:
error domain=gcdasyncsocketerrordomain code=7 socket closed by remote peer
此错误一般由于服务端关闭而导致出错,出现此问题的一般排查步骤:
服务端要将新连接的socket强引用,否则会出现此错误。
@property (nonatomic, strong) NSMutableArray *socketsArray;
- (void)viewDidLoad {
_socketsArray = [[NSMutableArray alloc] init];
}
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket {
[_socketsArray addObject:newSocket];
[newSocket readDataWithTimeout:-1 tag:0];
}
没有规律发送心跳或者心跳间隔过长。“Socket closed by remote peer” - GCDAsyncSocket Error Code 7中有人尝试将心跳从10分钟改为5分钟之后解决了此错误,可参考。由于我7秒发送一次心跳,因此排除此可能性。
是否使用相同的凭证从不同的客户端登录,并且在服务器设置中有这样的设置:如果有资源冲突,立即踢出另一个资源,在服务器>服务器设置>资源策略。
经过排查,发现存在以下问题:
socket的代理回调队列放在子线程。
//启动服务
_severPort = [OsxPortListHelper port];
_socketDelegateQueue = dispatch_queue_create("socket_delegate_queue", NULL);//注意成员变量引用,否则会释放
_serverSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_socketDelegateQueue];
[_serverSocket acceptOnPort:_severPort error:nil];
每个socket writeData:之后应发送readDataWithTimeout:方法,告诉代理接收数据。
[sock writeData:data withTimeout:-1 tag:0];
[sock readDataWithTimeout:-1 tag:0];
定时器改用_sendHeartBeatTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _socketDelegateQueue);
方式。
socket closed by remote peer gcdasyncsocket
写网络视频监视器中的总结 (一)