1. 程式人生 > >iOS自定義協議中的byte使用

iOS自定義協議中的byte使用

自定義的簡單協議一般包括訊息頭部,訊息碼,訊息體,校驗碼尾部,一個專案裡面用到的頭部和尾部一般都是固定的,訊息碼用來標識是哪一條訊息,校驗碼用來校驗資料完整性

  • 一些需要相容多端的開發的時候,可能會遇到使用自定義協議,比如與硬體通訊或者使用socket的時候,接受的資料是按約定協議的位元組陣列,寫資料的時候也需要按照協議來發送資料,這時就涉及到byte陣列的的寫入和解析(很久前記錄在quiver上的了,今天有空整理了下,沒洗看,可能會有錯誤,贅述)

首先簡單說下基礎概念:1 byte = 8 bit,一位元組需要用8個二進位制數來表示,0x00 = 0000 0000,一個十六進位制數需要四位二進位制表示 >> 1

,右移一位,相當於 * 2^1,也常用來擷取某幾位二進位制,&0xFF:相當於&1111 1111,

  • 正題開始

  • 位移操作 <<, >>

>> :表示向右邊位移, 右邊補零
<<:左位移,
i = 10011100;
i >> 3 —表示-> 10011100 -> 00010011 向右位移三位,多餘的丟棄,左邊補零
i << 3 —表示->10011100 -> 11100000 向左位移三位,多餘的丟棄,右邊補零

  • 一個位元組 = 八位二進位制

0xff:這裡一個f 表示四位二進位制,即表示 1111 111
不失一般性:0xff00: —>表示 1111 1111 0000 0000
當一個 byte &0xff 的時候,表示和 1111 111 做位與 運算 ,作用是保持二進位制原碼一致,無符號,擷取 低八位,因為 和 1111 111 做位與 運算的時候,在這個數之前的都會變成 0,所以 起到擷取 低位的作用

int 轉16 進位制
  • M_1
    int四位元組 資料是32位二進位制數 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];
        }
}
  • 實際上這些都算比較基本的東西,大學數電剛開始的時候也就這些什麼進位制編碼之類的,只是開發的時候可能用到對位元組資料操作的比較少,平時用的都是一些封裝過的框架或者常見的資料型別,做個記錄吧