錯誤描述
- 環(huán)境:AsyncSocket客戶端建立TCP連接
- 情景1:在網(wǎng)絡連接正常情況下提陶,啟動應用程序框都,對socket的連接确丢、斷開茫多、重連等操作都沒有問題祈匙;
- 情景2:在網(wǎng)絡異常情況下啟動應用程序然后恢復網(wǎng)絡,或后臺切換網(wǎng)路時,socket無法正常通信,顯示連接成功,但是緊接著doCFReadStreamCallback回調(diào)中報錯天揖,然后就closeWithError
- domain=kCFStreamErrorDomainPOSIX, error=57
一:網(wǎng)上查閱在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];
}
}
?二.判斷各種網(wǎng)絡情況再選擇重新連接(實測解決問題)
-
1.先檢查有沒有在onSocket:willDisconnectWithError:中去重新創(chuàng)建socket并連接,如果有要去掉,正確應該在- (void)onSocketDidDisconnect:(AsyncSocket *)sock中重新連接,否則會造成closeWithError運行報錯
- 注意調(diào)用順序onSocket:willDisconnectWithError:->onSocketDidDisconnect:
2.根據(jù)網(wǎng)絡狀況判斷是否進行重連
3.此處沒有貼心跳包的代碼,如果需要自行添加.
typedef enum SocketStatus{
SocketOfflineByServer,
SocketOfflineByUser,
SocketOfflineByWifiCut,
}_SocketStatus;
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
//對收到的數(shù)據(jù)進行校驗&分析&處理
NSDictionary *infoDic=[NSJSONSerialization JSONObjectWithData:sock.unreadData options:NSJSONReadingAllowFragments error:nil];
NSLog(@"Socket發(fā)送失敗 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);
}
}