iOS-二进制协议的封装

iOS-二进制协议的封装

对于在SDK socket通信时会存在二进制协议的通信模式,对于此根据以往的工作内容进行小结:

首先在socket通讯中可以有字符串协议和二进制协议,通过协议来达到通讯的目的。对于字符串协议就是通过字符串来制定通讯的标准模式是“string”-“value”模式,通过XML或者json来达到网络传输,解析封装也是基于XML或者json进行信息提取。

对于二进制协议,在C语言是通过struct对协议进行封装,在iOS中使用的是OC,在OC中你也可以通过C语言对二进制协议进行封装,但是在C语言和OC混合变成就会感觉好不爽。所以今天就通过OC谈一谈二进制协议封装。

首先C语言对协议的封装进行分解,一个Struct结构体无非就是协议值的布局,协议值占的byte数,包的大小,结构体的内存块。通过一一对应关系,,我们就可以把结构体映射到OC的类中。下面通过一个简单的协议封装结构题和OC的协议封装来理解:

比如现在有一个协议的C语言结构如下

struct {char one; //字符unsigned short two; //short类型unsigned int three; //int类型char * four; //字符串}BinaryProtocolStruct;

使用OC面向对象的思想对该协议进行封装

头文件:

@interface BinaryProtocolTest : NSObject-(id)initWithOne:(int)one andTwo:(int)two andThree:(int)three andFour:(NSString *)string;-(id)initWithData:(NSData *)data;-(void)setOne:(int)one;-(void)setTwo:(int)two;-(void)setThree:(int)three;-(void)setFour:(NSString *)four;-(int)getOne;-(int)getTwo;-(int)getThree;-(NSString *)getFour;-(NSMutableData *)getProtocolData;-(int)getProtocolSize;+(int)getProtocolSize;@end实现文件:

//协议的固定大小#define ProtocolSize 39@implementation BinaryProtocolTest{NSMutableData *_protocolData; //协议的内存块int _protocolSize;//协议的内存块大小struct{unsigned short one_offset:8;unsigned short one_len:8;unsigned short two_offset:8;unsigned short two_len:8;unsigned short three_offset:8;unsigned short three_len:8;unsigned short four_offset:8;unsigned short four_len:8;}_protocolLayout;//协议的内存块布局,主要由offset和size决定}-(void)initProtocolLayout{_protocolLayout.one_offset=0;_protocolLayout.one_len = 1;_protocolLayout.two_offset = 1;_protocolLayout.two_len = 2;_protocolLayout.three_offset = 3;_protocolLayout.three_len =4;_protocolLayout.four_offset =7;_protocolLayout.four_len =32;_protocolSize = 39;}/* *该方法的主要作用是当你想使用该协议封装自己的数据时使用 */-(id)initWithOne:(int)one andTwo:(int)two andThree:(int)three andFour:(NSString *)four{self = [super init];if (self) {[self initProtocolLayout]; //先初始化协议的内存布局_protocolData = [[NSMutableData alloc]init];//初始化协议的内存块[_protocolData resetBytesInRange:NSMakeRange(0, _protocolSize)];//设定内存块的大小//one为char类型不需要进行网络主机传输模式转换,把one的值写入到内存块中unsigned char tempOne = one;[_protocolData replaceBytesInRange:NSMakeRange(_protocolLayout.one_offset, _protocolLayout.one_len) withBytes:&tempOne length:_protocolLayout.one_len];//two为unsigned short 类型,所以要进行网络主机的传输字节顺序的转换 htons ->short 类型的主机存储->网络的网络存储,并写入内存块unsigned short tempTwo = two;tempTwo = htons(tempTwo);[_protocolData replaceBytesInRange:NSMakeRange(_protocolLayout.two_offset, _protocolLayout.two_len) withBytes:&tempTwo length:_protocolLayout.two_len];//three 为int类型 所以要进行网络主机的传输字节顺序的转换 htonl ->short 类型的主机存储->网络的网络存储,并写入内存块unsigned int tempThree = three;tempThree = htonl(tempThree);[_protocolData replaceBytesInRange:NSMakeRange(_protocolLayout.three_offset, _protocolLayout.three_len) withBytes:&tempThree length:_protocolLayout.three_len];//four为字符串不需要进行存储转换NSData *tempFour = [four dataUsingEncoding:NSUTF8StringEncoding];[_protocolData replaceBytesInRange:NSMakeRange(_protocolLayout.four_offset, _protocolLayout.four_len) withBytes:tempFour.bytes length:_protocolLayout.four_len];}return self;}-(id)init{self = [super init];if (self) {[self initProtocolLayout];_protocolData = [[NSMutableData alloc] init];[_protocolData resetBytesInRange:NSMakeRange(0, _protocolSize)];}return self;}-(id)initWithData:(NSData *)data{self = [super init];if (self) {[self initProtocolLayout];if (data.length!=_protocolSize) {return nil; //参数过滤,如果返回的数据包的大小不对,就返回}_protocolData = [[NSMutableData alloc] init];[_protocolData resetBytesInRange:NSMakeRange(0, _protocolSize)];[_protocolData replaceBytesInRange:NSMakeRange(0, _protocolSize) withBytes:data.bytes length:_protocolSize];}return self;}//one的设置 char-(void)setOne:(int)one{if (_protocolData.length !=_protocolSize) {//one为char类型不需要进行网络主机传输模式转换,把one的值写入到内存块中unsigned char tempOne = one;[_protocolData replaceBytesInRange:NSMakeRange(_protocolLayout.one_offset, _protocolLayout.one_len) withBytes:&tempOne length:_protocolLayout.one_len];}}//two的设置 unsigned short-(void)setTwo:(int)two{if (_protocolData.length !=_protocolSize) {//two为unsigned short 类型,所以要进行网络主机的传输字节顺序的转换 htons ->short 类型的主机存储->网络的网络存储,并写入内存块unsigned short tempTwo = two;tempTwo = htons(tempTwo);[_protocolData replaceBytesInRange:NSMakeRange(_protocolLayout.two_offset, _protocolLayout.two_len) withBytes:&tempTwo length:_protocolLayout.two_len];}}//three的设置 int-(void)setThree:(int)three{if (_protocolData.length !=_protocolSize) {//three 为int类型 所以要进行网络主机的传输字节顺序的转换 htonl ->short 类型的主机存储->网络的网络存储,并写入内存块unsigned int tempThree = three;tempThree = htonl(tempThree);[_protocolData replaceBytesInRange:NSMakeRange(_protocolLayout.three_offset, _protocolLayout.three_len) withBytes:&tempThree length:_protocolLayout.three_len];}}//four的设置 string-(void)setFour:(NSString *)four{if (_protocolData.length !=_protocolSize) {//four为字符串不需要进行存储转换NSData *tempFour = [four dataUsingEncoding:NSUTF8StringEncoding];[_protocolData replaceBytesInRange:NSMakeRange(_protocolLayout.four_offset, _protocolLayout.four_len) withBytes:tempFour.bytes length:_protocolLayout.four_len];}}//get one-(int)getOne{if (_protocolData.length !=_protocolSize) {unsigned char temp;[_protocolData getBytes:&temp range:NSMakeRange(_protocolLayout.one_offset, _protocolLayout.one_len)];return temp;}return 0;}//get two-(int )getTwo{if (_protocolData.length !=_protocolSize) {unsigned short temp;[_protocolData getBytes:&temp range:NSMakeRange(_protocolLayout.two_offset, _protocolLayout.two_len)];//short网络存储转本地存储return ntohs(temp);}return 0;}//get three-(int)getThree{if (_protocolData.length !=_protocolSize) {unsigned char temp;[_protocolData getBytes:&temp range:NSMakeRange(_protocolLayout.three_offset, _protocolLayout.three_len)];//int网络存储转本地存储return ntohl(temp);}return 0;}//get four-(NSString *)getFour{if (_protocolData.length !=_protocolSize) {NSData *temp = [_protocolData subdataWithRange:NSMakeRange(_protocolLayout.four_offset, _protocolLayout.four_len)];NSString *tempStr = [[NSString alloc]initWithUTF8String:temp.bytes];return tempStr;}return nil;}-(NSMutableData *)getProtocolData{return _protocolData;}-(int)getProtocolSize{return _protocolSize;}+(int)getProtocolSize{return ProtocolSize;}@end 小结:面向对象的思想封装,使数据实体和对数据实体的操作相关连

你看报表时,梅里雪山的金丝猴刚好爬上树尖。

iOS-二进制协议的封装

相关文章:

你感兴趣的文章:

标签云: