iOS漫步者iosiOS开发笔记

iOS基础之字节处理(NSData,Byte,NSString转

2018-03-15  本文已影响329人  留个念想给昨天
漫步

TCP传输协议:前2个子节为一个固定的字符,这里以0x809B为例,接着为4个子节(存放content的长度),然后为传输的内容content

TCP传输协议

以下内容都在Demo中,有兴趣可以下载

一、 拼接方式1---使用Byte数组

这里以传输一张图片为例

1.1前期准备---获取一张图片的大小
    NSString  *path=  [[NSBundle mainBundle] pathForResource:@"ceshi" ofType:@"jpeg"];
    NSData* content = [NSData dataWithContentsOfFile:path];
    int value = (int)content.length;
1.2 将长度value转换为4个字节
Byte byteData[4] = {};
    
byteData[0] =(Byte)((value & 0xFF000000)>>24);
    
byteData[1] =(Byte)((value & 0x00FF0000)>>16);
    
byteData[2] =(Byte)((value & 0x0000FF00)>>8);
    
byteData[3] =(Byte)((value & 0x000000FF));
//转换为4个字节
1.3 拼接固定字符并转为NSData
Byte byte[] = {0x80,0x9B,byteData[0],byteData[1],byteData[2],byteData[3]};
NSData *temphead = [[NSData alloc]initWithBytes:byte length:6];
1.4 拼接传输的数据(图片)
//拼接content
NSMutableData *m_data = [[NSMutableData alloc] init];
[m_data appendData:temphead];
[m_data appendData:content];

二、 拼接方式2---使用十六进制转换

2.1前期准备---获取一张图片的大小
    NSString  *path=  [[NSBundle mainBundle] pathForResource:@"ceshi" ofType:@"jpeg"];
    NSData* content = [NSData dataWithContentsOfFile:path];
    int value = (int)content.length;
2.2 将长度value转换十六进制string
//将长度转为十进制string
NSString* decimalString = [NSString stringWithFormat:@"%d",value];
//将十进制string转为十六进制并保证长度为8
NSString* firstHex = [decimalString decimalToHexWithLength:8];//私有方法(见Demo)
2.3 将十六进拼接固定字符并转为NSData
//将十六进制拼接上809B
NSString* hexString = [NSString stringWithFormat:@"809B%@",firstHex];
//将十六进制转为NSData
NSData* temphead = [hexString convertBytesStringToData];
2.4 拼接传输的数据(图片)
//拼接content
NSMutableData *m_data = [[NSMutableData alloc] init];
[m_data appendData:temphead];
[m_data appendData:content];

三、 解析数据

这里是模拟服务器返回的数据
因为发送给服务器内容的格式根服务器返回的内容的格式相同,所以这里我们直接解析我们发送给服务器的数据就可以

3.1 获取头部数据
NSData *head = [_receiveData subdataWithRange:NSMakeRange(0, 6)];//取得头部数据
NSData *lengthData = [head subdataWithRange:NSMakeRange(2, 4)];//取得长度数据
3.2 将4个字节的数据还原为content的长度
1 将lengthData转为16进制数
NSString* hexString = [lengthData convertDataToHexStr];
2 将16进制数转为10进制
NSInteger length = [[hexString hexToDecimal]integerValue];//得出content长度
3.3 取出content的内容
NSInteger complateDataLength = length + 6;//算出一个包完整的长度(内容长度+头长度)
if (_receiveData.length >= complateDataLength)//如果缓存中数据够一个整包的长度
{
    //这个data即为我们传出去的数据
    NSData *data = [_receiveData subdataWithRange:NSMakeRange(6, length)];//截取一个包的长度(处理粘包)
    //显示到程序上
    [self.resultImage setImage:[UIImage imageWithData:data]];
}
image.png image.png

四、 进制、Byte、Byte数组、NSData的相互转换(参考Demo)

#import "NSString+SwitchData.h"

@implementation NSString (SwitchData)
/**
 带子节的string转为NSData
 
 @return NSData类型
 */
-(NSData*) convertBytesStringToData {
    NSMutableData* data = [NSMutableData data];
    int idx;
    for (idx = 0; idx+2 <= self.length; idx+=2) {
        NSRange range = NSMakeRange(idx, 2);
        NSString* hexStr = [self substringWithRange:range];
        NSScanner* scanner = [NSScanner scannerWithString:hexStr];
        unsigned int intValue;
        [scanner scanHexInt:&intValue];
        [data appendBytes:&intValue length:1];
    }
    return data;
}
/**
 十进制转十六进制
 
 @return 十六进制字符串
 */
- (NSString *)decimalToHex {
    long long int tmpid = [self intValue];
    NSString *nLetterValue;
    NSString *str = @"";
    long long int ttmpig;
    for (int i = 0; i < 9; i++) {
        ttmpig = tmpid % 16;
        tmpid = tmpid / 16;
        switch (ttmpig) {
            case 10:
                nLetterValue = @"A";
                break;
            case 11:
                nLetterValue = @"B";
                break;
            case 12:
                nLetterValue = @"C";
                break;
            case 13:
                nLetterValue = @"D";
                break;
            case 14:
                nLetterValue = @"E";
                break;
            case 15:
                nLetterValue = @"F";
                break;
            default:
                nLetterValue = [[NSString alloc]initWithFormat:@"%lli", ttmpig];
        }
        str = [nLetterValue stringByAppendingString:str];
        if (tmpid == 0) {
            break;
        }
    }
    return str;
}
/**
 十进制转十六进制
 length   总长度,不足补0
 @return 十六进制字符串
 */
- (NSString *)decimalToHexWithLength:(NSUInteger)length{
    NSString* subString = [self decimalToHex];
    NSUInteger moreL = length - subString.length;
    if (moreL>0) {
        for (int i = 0; i<moreL; i++) {
            subString = [NSString stringWithFormat:@"0%@",subString];
        }
    }
    return subString;
}
/**
 十六进制转十进制
 
 @return 十进制字符串
 */
- (NSString *)hexToDecimal {
    return [NSString stringWithFormat:@"%lu",strtoul([self UTF8String],0,16)];
}
/*
 二进制转十进制
 
 @return 十进制字符串
 */
- (NSString *)binaryToDecimal {
    int ll = 0 ;
    int  temp = 0 ;
    for (int i = 0; i < self.length; i ++) {
        temp = [[self substringWithRange:NSMakeRange(i, 1)] intValue];
        temp = temp * powf(2, self.length - i - 1);
        ll += temp;
    }
    NSString * result = [NSString stringWithFormat:@"%d",ll];
    return result;
}
/**
 十进制转二进制
 
 @return 二进制字符串
 */
- (NSString *)decimalToBinary {
    NSInteger num = [self integerValue];
    NSInteger remainder = 0;      //余数
    NSInteger divisor = 0;        //除数
    NSString * prepare = @"";
    
    while (true) {
        remainder = num%2;
        divisor = num/2;
        num = divisor;
        prepare = [prepare stringByAppendingFormat:@"%d",(int)remainder];
        
        if (divisor == 0) {
            break;
        }
    }
    
    NSString * result = @"";
    for (NSInteger i = prepare.length - 1; i >= 0; i --) {
        result = [result stringByAppendingFormat:@"%@",
                  [prepare substringWithRange:NSMakeRange(i , 1)]];
    }
    return [NSString stringWithFormat:@"%08d",[result intValue]];
}
@end
@implementation NSData (SwitchData)

/**
 NSData 转  十六进制string
 
 @return NSString类型的十六进制string
 */
- (NSString *)convertDataToHexStr{
    if (!self || [self length] == 0) {
        return @"";
    }
    NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[self length]];
    
    [self enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
        unsigned char *dataBytes = (unsigned char*)bytes;
        for (NSInteger i = 0; i < byteRange.length; i++) {
            NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
            if ([hexStr length] == 2) {
                [string appendString:hexStr];
            } else {
                [string appendFormat:@"0%@", hexStr];
            }
        }
    }];
    
    return string;
}

/**
 NSData 转 NSString
 
 @return NSString类型的字符串
 */
- (NSString *)dataToString {
    Byte *bytes = (Byte *)[self bytes];
    NSMutableString *string = [[NSMutableString alloc] init];
    for(int i = 0; i< [self length]; i++) {
        if (i == 0) {
            [string appendString:[NSString stringWithFormat:@"%hhu",bytes[i]]];
        }else {
            [string appendString:[NSString stringWithFormat:@",%hhu",bytes[i]]];
        }
    }
    return string;
}
@end

写在最后:
希望这篇文章对您有帮助。当然如果您发现有可以优化的地方,希望您能慷慨的提出来。最后祝您工作愉快!

上一篇下一篇

猜你喜欢

热点阅读