AsyncSocket库使用方法

AsyncSocket库使用方法

AsyncSocket是封装了CFSocket和CFSteam的TCP/IP socket网络库。它提供了异步操作,本地cocoa类的基于delegate的完整支持

库中包含两部分:GCD和RunLoop

CGD是基于线程的  另一种是基于RunLoop的

  • AsyncSocket类是支持TCP的
  • AsyncUdpSocket是支持UDP的
  • CGDAsyncSocket类是支持TCP的
  • CGdAsyncUdpSocket是支持UDP的

CGdAsyncSocket使用方法

 asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    NSError *error = nil;
    if (![asyncSocket connectToHost:@"" onPort:123 error:nil]) {
        NSLog(@"%@",error);
    }

AsyncSocket使用方法

//建立socket长连接
- (void)startConnectSocket
{
    self.socket = [[AsyncSocket alloc] initWithDelegate:self];
    [self.socket setRunLoopModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
    if ( ![self SocketOpen:HOST port:PORT] )
    {
       //连接正常,可以和服务器交互
        NSLog(@"正在尝试连接...");
       
        
    }
    
}
- (NSInteger)SocketOpen:(NSString*)addr port:(NSInteger)port
{
    
    if (![self.socket isConnected])
    {
        NSError *error = nil;
        [self.socket connectToHost:addr onPort:port withTimeout:TIME_OUT error:&error];
    }
    
    return 0;
}

#pragma mark - 断开连接 用户手动断开连接
//cutOffSocket是用户断开连接之后,不在尝试重新连接。
-(void)cutOffSocket
{
    self.socket.userData = SocketOfflineByUser;
    [self.socket disconnect];
}

#pragma mark - 发送消息
- (void)sendMessage:(id)message
{
    //像服务器发送数据
    NSData *cmdData = [message dataUsingEncoding:NSUTF8StringEncoding];
    [self.socket writeData:cmdData withTimeout:WRITE_TIME_OUT tag:1];
    
}


#pragma mark - socketDelegate

#pragma mark - socket断开之后会回调:
- (void)onSocketDidDisconnect:(AsyncSocket *)sock
{
    
    NSLog(@"7878 对不起,连接失败 %ld",sock.userData);
    
    if (sock.userData == SocketOfflineByServer) {
        NSLog(@"原因:服务器掉线");
        // 服务器掉线,重连
        [self startConnectSocket];
    }
    else if (sock.userData == SocketOfflineByUser) {
        NSLog(@"用户断开连接");
        // 如果由用户断开,不进行重连
        return;
    }else if (sock.userData == SocketOfflineByWifiCut) {
        NSLog(@"WiFi断开");
        // wifi断开,不进行重连
        return;
    }
    
}


#pragma mark -  socket出错回调
//socket出错会回调onSocket:willDisconnectWithError:方法,可以通过unreadData来读取来不及读取的buffer。
- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
    NSData * unreadData = [sock unreadData]; // ** This gets the current buffer
    if(unreadData.length > 0) {
        [self onSocket:sock didReadData:unreadData withTag:0]; // ** Return as much data that could be collected
    } else {
        
        NSLog(@" 即将连接出错 %ld",sock.userData);
        if (sock.userData == 0) {
            NSLog(@"出错原因:服务器连接出错");
            NSLog(@"错误描述:%@",[err description]);
        }
        //wifi断开之后,会回调onSocket:willDisconnectWithError:方法,err.code == 57,这个时候设置self.socket.userData = SocketOfflineByWifiCut。
        if (err.code == 57) {
            self.socket.userData = SocketOfflineByWifiCut;
        }
    }
    
}


#pragma mark - 接收到新的socket回调方法
- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket
{
    NSLog(@"didAcceptNewSocket");
}

#pragma mark - 连接成功回调方法
//在连接成功的回调方法里,启动定时器,每隔2秒向服务器发送固定的消息来检测长连接。(这个根据服务器的需要就可以了)
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
    //这是异步返回的连接成功,
    NSLog(@"已连接到服务器");
    
    //通过定时器不断发送消息,来检测长连接
    self.heartTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(checkLongConnectByServe) userInfo:nil repeats:YES];
    [self.heartTimer fire];
}

// 心跳连接
-(void)checkLongConnectByServe{
    
    // 向服务器发送固定可是的消息,来检测长连接
    NSString *longConnect = @"connect is here";
    NSData   *data  = [longConnect dataUsingEncoding:NSUTF8StringEncoding];
    [self.socket writeData:data withTimeout:1 tag:1];
}



#pragma mark - 接受消息成功之后回调
- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    //服务端返回消息数据量比较大时,可能分多次返回。所以在读取消息的时候,设置MAX_BUFFER表示每次最多读取多少,当data.length < MAX_BUFFER我们认为有可能是接受完一个完整的消息,然后才解析
    if( data.length < MAX_BUFFER )
    {
        //收到结果解析...
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
        NSLog(@"%@",dic);
        //解析出来的消息,可以通过通知、代理、block等传出去
        
    }
    
    
    [self.socket readDataWithTimeout:READ_TIME_OUT buffer:nil bufferOffset:0 maxLength:MAX_BUFFER tag:0];
    
}

#pragma mark - 发送消息成功之后回调
//发送消息成功之后会调用onSocket:didWriteDataWithTag:,在这个方法里可以进行读取消息。
- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    //读取消息
    [self.socket readDataWithTimeout:-1 buffer:nil bufferOffset:0 maxLength:MAX_BUFFER tag:0];
}


你可能感兴趣的:(AsyncSocket库使用方法)