• 关于AsyncSocket


       

     

         写篇博客,在我项目中用到了一个很重要的第三方---AsyncSocket,写下我对AsyncSocket使用心得。我的项目中是APP对硬件直接交互,APP对硬件发指令的时候不需要经过服务端,要经过采集端,此处我要感谢曾在北京天一众合java工程师杜强(此交互中担任采集工程师)。

    1. AsyncSocket是一种很底层的数据交互控件,主要以拼接字节流来完成之间的数据传递,大家可能说字节流这东西如何拼接,是否操作很简单呢,其实我想告诉你,这对于技术大牛来说简单,对于初学者来说不见的容易得手。下面我先展现下文档。关于文档,有HTTP,TCP大家可能说TCP文档很少了解,那么我给你们展现下。

    “下发即时音频”:

    大家看到的这个文档就是TCP文档,首先我拿“下发即时音频”作为一个列子拿给大家讲。可以看出,信息头下面都有注明几个字节,信息头2个字节,长度2个字节,等等。在上面我就说过,这个要以拼接字节流来进行数据交互。所以字节流已经给注明。信息头不变,表示是什么指令,结束标志表示是该指令的结束。该指令中还有长度,序列号,控制命令,声音文件,这些正是你要拼接字节流的地方。那么我下面根据代码给详细讲解下。

    这里我封装了一个方法,首先把10进制转化为16进制,然后再转化Ascll码,这里Byte head[] = {0x42,0x68};就是转化为Ascll后,拼接上。Byte serialNumbe[] = {0x00,0x01};为序列号, Byte controlCommand[] = {0x00,0x02};为控制命令。

     NSData * infoHeaderData = [NSData dataWithBytes:head length:2];转化为data类型。  NSInteger  totallength  =  2+2+Data.length ;其中此处的Data,就是声音文件,此处是加上声音文件的长度,但不是我们要的最终总长度。 NSMutableData *sendData = [[NSMutableData alloc] init];此处sendData是我们最终是拼接好的也是我们要的该指令的总长度。我在做此处的时候进制转化很繁琐。要把二进制转化为十进制,再转化为十六进制,再转化为Ascll码值,没有找到直接转化为十六进制的方法也许是我太过繁琐。我们对拼接字节流后是不是该进行交互了啊,下面我再对AsyncSocket怎么用进行详细讲解下。

    AsyncSocket

    1.首先要握手,就是连接Socket端口:self.socket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    此处我选择调用子线程,因为交互时怕对线程造成影响,对语音发送到收到要求时间短,不能有延迟。然后就是连接端口,只要是TCP都会给你提供端口号:[self.socket connectToHost:@"hahahahaha" onPort:1234 error:nil];此处“hahahahaha”是你们的端口号,“1234”是你们端口号密码。然后再 self.socket.delegate = self;设置好委托。此处Socket以握手成功。
    2.socket的回调方法:

    -(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
    {
        
        [sock readDataWithTimeout:-1 tag:0];
        
        
        [sock readDataWithTimeout:-1 tag:1];


          此处是你要写的拼接好的字节流指令。发送方法;注意要标注好tag值,以分清是第几个指令方便你后面收到回复执行事件
        
        
    }
    - (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag;
    {
       

        NSLog(@" %ld 成功",tag);
        此处是你发送的指令是否成功;
        
    }
    -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
    {
        
       
        
        [self.socket readDataWithTimeout:-1 tag:1];
        [self.socket readDataWithTimeout:-1 tag:0];

        此处是发送成功后调用次方法,根据返回值再执行事件;

     Byte byteTest;
        byteTest = [self getDataByteWithIndex:8 WithData:data];


    }

    此时返回值不是

    //通过index获取data中的值
    -(Byte) getDataByteWithIndex : (int) index WithData: (NSData *)data
    {
        Byte byteTest = -1;
        if (data) {
            if (index < data.length) {
                NSRange range = {index, 1};
                [data getBytes:&byteTest range: range];
            }
        }
        return  byteTest;
    }
    此处我根据返回值如0000001000200;此处是十六制数,不是string类型的。我的要求是取出第几个数(如第8位数)

    说道这里相信你对Socket已经有个大概的了解了我再给你一个指令较为复杂的TCP指令。

    此处你要拼接的字节流有长度,序列号,控制命令,用户ID长度,用户,接受时间长度,接受时间,app版本号长度,app版本号,这里你共需要拼接9个字节流。都需要最终转化为Ascll,用户名也一样。您能拼接出来一个方法吗?下面我给展现下我封装这个指令的方法:

    //下发到所有卡指令
    -(NSData *)allaudiocard:(NSString *)name cardString:(NSString *)card version:(NSString *)String
    {
        
        Byte head[] = {0x42,0x68};
        Byte serialNumbe[] = {0x00,0x01};
        //Byte controlCommand[] = MyAudio0x0001;
        Byte controlCommand[] = {0x00,0x01};
        //    NSString * idString = @"cxylmm";
        Byte end[] = {0xd,0xa};
        NSData * infoHeaderData = [NSData dataWithBytes:head length:2];
        NSData * serialNumberData = [NSData dataWithBytes:serialNumbe length:2];
        NSData * controlCommandData = [NSData dataWithBytes:controlCommand length:2];
        
        NSData *idData = [name dataUsingEncoding:NSUTF16BigEndianStringEncoding];
        NSInteger idLength = idData.length;
        Byte idLenByte[] ={0,0};
        idLenByte[0] =(idLength>>8) &0xFF;
        idLenByte[1] =idLength &0xFF;
        NSData * idLengthData = [NSData dataWithBytes:idLenByte length:2];
        
        NSDateFormatter * formate = [[NSDateFormatter alloc] init];
        [formate setDateFormat:@"yyyyMMddHHmmss"];
        NSString * dateString = [formate stringFromDate:[NSDate date]];
        NSData * dateData = [dateString dataUsingEncoding:NSUTF8StringEncoding];
        NSInteger datelength = [dateData length];
        Byte arr[] ={0, 0};
        arr[0] =(datelength>>8) &0xFF;
        arr[1] = datelength &0xFF;
        NSData * dateLengthData = [NSData dataWithBytes:arr length:2];
        
        //    NSString * appversion = @"1.2";
        NSData * appVersionData = [String dataUsingEncoding:NSASCIIStringEncoding];
        NSInteger appversonlength = appVersionData.length;
        
        Byte arra[] = {0 ,0};
        arra[0] =(appversonlength>>8) &0xFF;
        arra[1] = appversonlength &0xFF;
        
        NSData * appversionLengthData = [NSData dataWithBytes:arra length:2];
        
        //    NSString *cards = @"0210000000000369,0210000000000370";
        NSData *cardsData = [card dataUsingEncoding:NSASCIIStringEncoding];
        NSUInteger cardsnuberlength = [cardsData length];
        
        int  totallength  =  2+2+2+idLength+2+datelength+2+appversonlength+cardsnuberlength ;
        //    NSData * totalLengthData = [[NSString stringWithFormat:@"%d",totallength] dataUsingEncoding:NSUTF8StringEncoding];
        
        Byte totalByte[] = {0,0};
        totalByte[0] = (totallength >> 8) & 0xFF;
        totalByte[1] = totallength & 0xFF;
        NSData *totalLengthData = [NSData dataWithBytes:totalByte length:2];
        
        NSData * endData = [NSData dataWithBytes:end length:2];
        
        NSMutableData *sendData = [[NSMutableData alloc] init];
        [sendData appendData:infoHeaderData];
        [sendData appendData:totalLengthData];
        [sendData appendData:serialNumberData];
        [sendData appendData:controlCommandData];
        [sendData appendData:idLengthData];
        [sendData appendData:idData];
        [sendData appendData:dateLengthData];
        [sendData appendData:dateData];
        [sendData appendData:appversionLengthData];
        [sendData appendData:appVersionData];
        [sendData appendData:cardsData];
        [sendData appendData:endData];
        
        return [NSData dataWithData:sendData];



    }
    写到这里能明白吗?这就是AsyncSocket的用法,不过socket还有其他类型,不单单只有这一种。针对写。

  • 相关阅读:
    PHP的命令行脚本调用
    JAVA使用jar命令制作可执行GUI程序
    PHP的代理模式
    PHP中的__clone()
    PHP使用反射动态加载第三方类
    NAT小记
    JAVA睡眠理发师代码记录
    PHP通过反射获得类源码
    PHP中单引号双引号的区别
    [转载]PHP导出数据库数据字典脚本
  • 原文地址:https://www.cnblogs.com/hanguoqing/p/4425594.html
Copyright © 2020-2023  润新知