美文网首页
iOS-TCP/IP协议传输数据常用的类型转换(欢迎补充~)

iOS-TCP/IP协议传输数据常用的类型转换(欢迎补充~)

作者: docManer | 来源:发表于2018-01-20 12:29 被阅读13次

    之前一直在做关于TCP/IP的项目,关于数据处理是最麻烦的,每次遇到新的数据类型就多一个新类的方法,导致很混乱,今天决定整理下,形成一个分类.

    写得不太好,有这方面经验的朋友可以在评论处留言,希望大家了一起完善~~~

    NSData+Category.h

    #import <Foundation/Foundation.h>
    
    @interface NSData (Category)
    
    // 注意:在NSData里面,<01>表示1个字节,用2个十六进制表示,1个十六进制表示4个bits
    
    #pragma mark - valueMehthod
    
    /// 返回包含8个字节Data,如:输入1 -> <00 00 00 00 00 00 00 01>
    + (instancetype)dataFromLong:(long)value ;
    /// 返回包含4个字节Data,如:输入1 -> <00 00 00 01>
    + (instancetype)dataFromInt:(int)value ;
    /// 返回包含2个字节Data,如:输入1 -> <00 01>
    + (instancetype)dataFromShort:(short)value ;
    /// 返回包含1个字节Data,如:输入1 -> <01> value必须小于256
    + (instancetype)dataOneByteFromShort:(short)value ;
    
    /// 返回long (必须满足:self.length >= 8)
    - (long)longValue ;
    /// 返回int (必须满足:self.length >= 4)
    - (int)intValue ;
    /// 返回short (必须满足:self.length >= 2)
    - (short)shortValue ;
    /// 返回short (必须满足:self.length >= 1)
    - (short)shortValueFromOneByteData ;
    
    
    #pragma mark - StringMethod
    
    /// 返回Data <01ff> -> "01ff" 如果传入参数 str 为 1ff, 则hexdata打印出:hexdata: <01ff>
    + (instancetype)hexDataFromHexString:(NSString *)hexString ;
    /// 十六进制字符串 <01ff> -> "01ff"
    + (NSString *)hexStringFromHexData:(NSData *)hexData ;
    
    /// 返回网络字节序的Data IPString -> data
    + (instancetype)ipDataFromIpString:(NSString *)ipString ;
    /// ip字符串
    + (NSString *)ipStringFromIpData:(NSData *)ipData ;
    
    /// 小端大端反转 (原本是小端,则变成大端;反之亦然)
    - (NSData *)reverseBitAndLittleEnd ;
    
    @end
    

    NSData+Category.m

    #import "NSData+Category.h"
    #import <arpa/inet.h>
    
    @implementation NSData (Category)
    
    #pragma mark -- valueMethod
    
    + (instancetype)dataFromLong:(long)value {
        return [NSMutableData dataWithBytes: &value length: sizeof(long)];
    }
    
    + (instancetype)dataFromInt:(int)value {
        return [NSMutableData dataWithBytes: &value length: sizeof(int)];
    }
    
    + (instancetype)dataFromShort:(short)value {
        return [NSMutableData dataWithBytes: &value length: sizeof(short)];
    }
    
    + (instancetype)dataOneByteFromShort:(short)value {
        NSAssert(value <= 256-1, @"value must be not overflow one byte value");
        return [NSMutableData dataWithBytes: &value length: sizeof(short)-1];
    }
    
    - (long)longValue {
        NSAssert(self.length >= 8, @"data length must be bigger than 8");
        long value;
        [self getBytes: &value length: sizeof(long)];
        return value;
    }
    
    - (int)intValue {
        NSAssert(self.length >= 4, @"data length must be bigger than 4");
        int value;
        [self getBytes: &value length: sizeof(int)];
        return value;
    }
    
    - (short)shortValue {
        NSAssert(self.length >= 2, @"data length must be bigger than 2");
        short value;
        [self getBytes: &value length: sizeof(short)];
        return value;
    }
    
    - (short)shortValueFromOneByteData {
        NSAssert(self.length >= 1, @"data length must be bigger than 1");
        short value;
        [self getBytes: &value length: 1];
        return value;
    }
    
    #pragma Mark - stringMethod
    /// 返回Data <01ff> -> "01ff" 如果传入参数 str 为 1ff, 则hexdata打印出:hexdata: <01ff>
    + (instancetype)hexDataFromHexString:(NSString *)hexString {
        if (!hexString || [hexString length] == 0)  return nil;
        
        NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
        NSRange range;
        if ([hexString length] % 2 == 0) {
            range = NSMakeRange(0, 2);
        } else {
            range = NSMakeRange(0, 1);
        }
        for (NSInteger i = range.location; i < [hexString length]; i += 2) {
            unsigned int anInt;
            NSString *hexCharStr = [hexString substringWithRange:range];
            NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
            
            [scanner scanHexInt:&anInt];
            NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
            [hexData appendData:entity];
            
            range.location += range.length;
            range.length = 2;
        }
        return hexData;
    }
    
    /// 十六进制字符串 <01ff> -> "01ff"
    + (NSString *)hexStringFromHexData:(NSData *)hexData {
        if (!hexData || [hexData length] == 0) return @"";
        
        NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[hexData length]];
        
        [hexData 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;
    }
    
    /// 返回网络字节序的Data IPString -> data
    + (instancetype)ipDataFromIpString:(NSString *)ipString {
        unsigned int s_addr = inet_addr([ipString UTF8String]);
        NSData *data = [NSMutableData dataWithBytes: &s_addr length: sizeof(unsigned int)];
        return data.reverseBitAndLittleEnd;
    }
    
    /// ip字符串
    + (NSString *)ipStringFromIpData:(NSData *)ipData {
        /// to unsigned int
        unsigned int value = *(unsigned int *)ipData.reverseBitAndLittleEnd.bytes;
        
        /// to char
        struct in_addr addr;
        addr.s_addr = value;
        char *strAddr = inet_ntoa(addr);
        
        return [NSString stringWithUTF8String:strAddr];
    }
    
    /// 小端大端反转 (原本是小端,则变成大端;反之亦然)
    - (NSData *)reverseBitAndLittleEnd {
        NSMutableData *littleEndData = [NSMutableData data];
        
        for(int i = 0; i < self.length; i++){
            NSData *subdata = [self subdataWithRange:NSMakeRange(self.length -i -1, 1)];
            [littleEndData appendData:subdata];
        }
        return littleEndData;
    }
    @end
    

    相关文章

      网友评论

          本文标题:iOS-TCP/IP协议传输数据常用的类型转换(欢迎补充~)

          本文链接:https://www.haomeiwen.com/subject/fettaxtx.html