Asyncsocket 使用总结

来源:互联网 发布:阿里云 oss cdn https 编辑:程序博客网 时间:2024/06/06 08:57
socket使用注意事项
1. timeout < 0时,表示没有超时;如果设置超时时间,并且socket超时之后,
   socket会断掉,需要重连

2. 用AsyncSocket连接服务器时,不管服务器有没有开,[client connectToHost:hostIP onPort:hostPort error:&err]
   这一句一直返回YES,所以判断服务器有没有连接成功

3. 当读的时候,需要判断长度是否足够,如果不够需要再次设置[socket readDataWithTimeout:-1 tag:0];

4.socket的3种连接状态:
   连接中:
   已连接:
   连接断开:

5.如何判断socket当前处于那种状态
  把asyncsocket.m文件中,- (BOOL)isDisconnected;方法放到asyncsocket.h文件中,该方法可判断当前socket是否处于连接断开状态;
- (BOOL)isConnected;可用来判断socket是否处于连接成功状态;
如果socket即不处于已连接和连接断开的状态,那么socket此时处于连接中的状态.处于连接中的socket不能再次发起连接,此时会报错

6.如何判断socket是用户主动断开还是服务器断开
当你需要主要断开连接时可以通过:

setUserData:(long)userData;

给socket.userData字段设一个值,在- (void)onSocketDidDisconnect:(AsyncSocket *)sock 方法中,根据socket.userData的值判断是用户主动断开还是服务器断开

7.一般一个应用生成一个socket实例来建立连接,不断新开实例会增加服务器压力

8.关于socket粘包问题

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
 {
    //把数据放到缓冲区
    [self.bufferData appendData:data];

    //获取包的总长度,PackageHeadBytesCount包中表示包大小的字节数
    NSData *headData = [self.bufferData subdataWithRange:NSMakeRange(0, PackageHeadBytesCount)];
    //获取包的大小
    short totalLen = [DataManager packageTotalLengthWithData:headData];

    if (self.bufferData.length < totalLen){
        NSLog(@"*** 包体长度 < 要的长度");
    }else if (self.bufferData.length > totalLen){
        //此种情况下发生了粘包,下面是处理粘包的步骤
        NSLog(@"*** 包体长度 > 要的长度");

        short newTotalLen = totalLen;

        while (self.bufferData.length >= newTotalLen) {
            NSUInteger leftLen = self.bufferData.length - newTotalLen;
            //从缓冲区取一包数据
            NSData *packageData = [self.bufferData subdataWithRange:NSMakeRange(0, newTotalLen)];

            NSData *leftData;

            if (leftLen == 0){

                leftData = [NSMutableData data];

            }else {

                leftData = [self.bufferData subdataWithRange:NSMakeRange(newTotalLen, leftLen)];

            }
            //缓冲区数据设置为减掉一包数据后的数据
            [self.bufferData setData:leftData];
            //处理拿到的一包数据
            [self handleRcvPackageData:packageData];

            if (leftLen == 0){
                break;
            }

            newTotalLen = [DataManager packageTotalLengthWithData:[NSData dataWithData:self.bufferData]];
        }
    }else {
        NSLog(@"*** 包体长度 == 要的长度");

        NSData *packageData = [NSData dataWithData:self.bufferData];
        //清空缓冲区
        self.bufferData = [NSMutableData data];
        //处理拿到的一个包的数据
        [self handleRcvPackageData:packageData];
    }
    [self.socket readDataWithTimeout:-1 tag:0];
}

9.如何保持socket的长连接状态
 通过发心跳来保持,心跳时间间隔可以和服务器来商定

10.socket不用时要进行如下操作:

    [self.socket setDelegate:nil];

    [self.socket disconnect];

    self.socket = nil;

11.timeout字段设为-1时,socket为一直等待的read或write

12.socket每次重连的时候要把缓冲区的数据清空(sessioninfo获取不到的原因)

1 0