iOS自定义协议中的byte使用

自定义的简单协议一般包括消息头部,消息码,消息体,校验码尾部,一个项目里面用到的头部和尾部一般都是固定的,消息码用来标识是哪一条消息,校验码用来校验数据完整性

  • 一些需要兼容多端的开发的时候,可能会遇到使用自定义协议,比如与硬件通信或者使用socket的时候,接受的数据是按约定协议的字节数组,写数据的时候也需要按照协议来发送数据,这时就涉及到byte数组的的写入和解析(很久前记录在quiver上的了,今天有空整理了下,没洗看,可能会有错误,赘述)

首先简单说下基础概念:1 byte = 8 bit,一字节需要用8位二进制数来表示,0x00 = 0000 0000,一个十六进制数需要四位二进制表示, << n ,左移n位,相当于 * 2^n,也常用来截取某几位二进制,&0xFF:相当于&1111 1111,

  • 正题开始

  • 位移操作 <<, >>

>> :表示向右边位移, 左边补零
<<:左位移,
i = 10011100;
i >> 3 —表示-> 10011100 -> 00010011 向右位移三位,多余的丢弃,左边补零
i << 3 —表示->10011100 -> 11100000 向左位移三位,移出位丢弃,右边补零

  • 一个字节 = 八位二进制

0xff:这里一个f 表示四位二进制,即表示 1111 1111
不失一般性:0xff00: —>表示 1111 1111 0000 0000
当一个 byte &0xff 的时候,表示和 1111 1111 做位与 运算 ,作用是保持二进制原码一致,无符号,截取 低八位,因为 和 1111 1111 做位与 运算的时候,在这个数之前的都会变成 0,所以 起到截取 低位的作用

int 转16 进制
  • M_1
    intint型会根据计算机系统来确定用多少位来表示,32位系统int型就是32位,16位系统就是16位,当然,现在的计算机大多数都是32位,64位的,大多数情况下,int还是使用32位表示,32位 四字节 数据是32位二进制数, 1 byte = 8bit ,所以需要四个来byte来表示 ,
    int a = 2312;
    byte b1 = a &0xff;没有位移 和 0xff 与运算 取 最低八位
    byte b2 = a >> 8 &0xff;向右位移八位之后 与运算,取 次低位
    byte b3 = a >> 16 &0xff;向右位移十六位之后 与运算,取 次高八位
    byte b4 = a >> 24 &0xff;向右位移二十四位之后 与运算,取 最高八位
  • M_2先进行 与运算
    byte b1 = a &0xff >>0;向右位移0位,因为0xff是八位二进制,和 0xff 与运算 取 最低八位
    byte b1 = a &0xff00 >>8;因为0xff00是十六位二进制,和 0xff00 与运算 取 最低十六位,右移八位,去掉低八位,剩下 16位中的高八位,即原数据集的次低八位
    byte b1 = a &0xff0000 >>16;因为0xff0000是二十四位二进制,和 0xff0000 与运算 取 最低二十四位,右移十六位,去掉低十六位,剩下 24位中的高八位,即原数据集的次高八位
    byte b1 = a &0xff000000 >>24;因为0xff000000是三十二位二进制,和 0xff000000 与运算 取 最低三十二位(因为int是32位,即没有截取),右移24位,去掉低24位,剩下 32位中的高八位,即原数据集的高八位

  • 对于二进制 十六进制十进制来说,在计算机中都是二进制表示,所以占多多少字节看是多少位的数,一字节八位 二进制,一位十六进制 在计算机中用 4位 二进制表示,所以:0x4 这样的一位十六进制 用四位二进制表示,即占0.5字节 byte,0xAA,这样的两位十六进制用八位二进制表示占一字节,0xABAC:四位十六进制用十六位二进制表示占两字节,一 bit 即代表一个二进制数 一字节八 bit (比特)

  • 在计算机中所有的东西都是二进制表示,所以汉字也是用二进制表示,特殊的某个二进制数 对应着某个汉字,所以获取的 data 数据,不管什么进制 只要对应的始汉字的都能转成汉字,汉字也能转成 各种进制的数据

  • 口水话就差不多吧,可能表述会有问题,下面贴上 几段代码


  • 写入数据的时候

(NSData *)WritMessage{
    Byte chCMD[15];
    int cul = 0;
	int iTemp;
	chCMD[cul++] = (Byte)0x18;
	chCMD[cul++] = (Byte)0x81;
	chCMD[cul++] = (Byte)0x35;
	chCMD[cul++] = 852%256;
	chCMD[cul++] = 852/256;
	//Client ID
	iTemp = (int)CNNUserInfo.Client_ID ;
	chCMD[cul++] = (Byte)(iTemp  & 0xFF);
	chCMD[cul++] = (Byte)((iTemp & 0xFF00) >> 8);
	chCMD[cul++] = (Byte)((iTemp & 0xFF0000) >> 16);
	chCMD[cul++] = (Byte)((iTemp & 0xFF000000) >> 24);
	//Group ID
	iTemp = (int)CNNUserInfo.Current_GroupID;
	chCMD[cul++] = (Byte)(iTemp  & 0xFF);
	chCMD[cul++] = (Byte)((iTemp & 0xFF00) >> 8);
	chCMD[cul++] = (Byte)((iTemp & 0xFF0000) >> 16);
	chCMD[cul++] = (Byte)((iTemp & 0xFF000000) >> 24);
	chCMD[cul++] = (Byte)0x7F;
	chCMD[cul++] = (Byte)0xF7;
    return [NSData dataWithBytes:chCMD length:15];
}

  • 读取数据
- (id)readData:(NSData *)data
{
    NSMutableDictionary *RealTimeDic = [NSMutableDictionary dictionary];
    Byte *chRevCP = (Byte*)[data bytes];
    int cul = 0;
    cul += 1;  //0x33
    
    int local_ack = chRevCP[cul++];
    if (local_ack == 0) {
        [RealTimeDic setObject:@(0) forKey:kDicKey_SuccessLabel];
    }else{
        [RealTimeDic setObject:@1 forKey:kDicKey_SuccessLabel];
    }
    //总数
    CNNUserInfo.Logger_Total = chRevCP[cul++];
    
    for(int i=0; i<LLBUserInfo.Logger_Total; i++)
    {
        Byte  nameByte[64];
        EquipmentModel *LoggerModel = [EquipmentModel new];
        NSMutableArray *passWayArr = [NSMutableArray new];
        Byte  snByte[10];
        for(int j=0; j<10; j++)
        {
           snByte[j] = chRevCP[cul++];
        }
        //编号
        LoggerModel.EquipmentCode= [[NSString alloc]initWithBytes:snByte length:10 encoding:LLBEncoding];
        for(int j=0; j<48; j++)
        {
            nameByte[j] = chRevCP[cul++];
        }
        //名称
        LoggerModel.EquipmentName = [[NSString alloc]initWithBytes:nameByte length:48 encoding:LLBEncoding];
        //数目
         LoggerModel.PassWayNumber = chRevCP[cul++];
        //================== 一 ========================
        PassWayModel *onePassWay = [PassWayModel new];
        onePassWay.Type = chRevCP[cul++];
        float high = ((chRevCP[cul]&0xFF) + (chRevCP[cul+1]&0xFF)*256 + (chRevCP[cul+2]&0xFF)*256*256 + (chRevCP[cul+3]&0xFF)*256*256*256)/(float)10.0;
        onePassWay.High = high;
        cul += 4;
        onePassWay.Low = ((chRevCP[cul]&0xFF) + (chRevCP[cul+1]&0xFF)*256 + (chRevCP[cul+2]&0xFF)*256*256 + (chRevCP[cul+3]&0xFF)*256*256*256)/(float)10.0;
        cul += 4;
        //小数点
         onePassWay.data_dot = chRevCP[cul++];
        Byte chtemp0[8];
        for(int j = 0; j < 8; j++)//长度先不使用
        {
            chtemp0[j] = chRevCP[cul++];
        }
        if (onePassWay.Type==8) {
           onePassWay.Symbol = [[NSString alloc]initWithBytes:chtemp0 length:8 encoding:LLBEncoding];
        }
}
  • 实际上这些都算比较基本的东西,大学数电刚开始的时候也就这些什么进制编码之类的,只是开发的时候可能用到对字节数据操作的比较少,平时用的都是一些封装过的框架或者常见的数据类型,做个记录吧
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用SwiftUI自定义iOS分段控件可以通过以下步骤实现: 1. 创建一个新的SwiftUI View,命名为SegmentedControl。 2. 在SegmentedControl定义一个枚举类型,用于表示分段控件的选项。 3. 在SegmentedControl定义一个@Binding属性用于绑定选的选项。 4. 在SegmentedControl使用ForEach循环遍历所有的选项,并将它们显示在分段控件。 5. 在ForEach循环使用Button显示每一个选项,并在按钮的action更新选的选项。 6. 为分段控件添加样式,例如设置选的选项的背景色和字体颜色等。 下面是一个简单的示例代码: ```swift enum SegmentedOption: String, CaseIterable { case option1 case option2 case option3 } struct SegmentedControl: View { @Binding var selectedOption: SegmentedOption var body: some View { HStack { ForEach(SegmentedOption.allCases, id: \.self) { option in Button(action: { self.selectedOption = option }) { Text(option.rawValue) .foregroundColor(self.selectedOption == option ? .white : .black) .padding(.horizontal, 20) .padding(.vertical, 10) .background(self.selectedOption == option ? Color.blue : Color.gray) .cornerRadius(10) } } } } } ``` 在使用时,只需要将SegmentedControl添加到需要显示的View,并将选的选项绑定到某个属性即可。例如: ```swift struct ContentView: View { @State private var selectedOption: SegmentedOption = .option1 var body: some View { VStack { SegmentedControl(selectedOption: $selectedOption) Text("Selected option: \(selectedOption.rawValue)") } } } ``` 这样就可以在界面上显示一个自定义iOS分段控件了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值