AndroidとSCM |ボード|インテリジェントハードウェア|スマートデバイス|データプロトコル|開発の概要

まず、起源

Androidのニーズは、多くの場合、ボード、対話するスマートデバイスの様々なプログラムで遭遇も、基本的な方法を伝える仕事BleSocket tcp/udpその最も重要なことはコミュニケーションがあるに... 协议协议协议その3倍を言うことが重要です。このようなデータパケットとして、デバイスとの相互作用の方法と相互作用する通信プロトコルの形式を定義するために使用されます。(包头—数据包长度—数据—校验位—包尾)

第二に、バイト数によって占められるように、各種データを管理する第一のプロセッサ

1、我々は最終的に、バイナリまたはバイトコードによって識別することができ、様々なマシンに変換するコードを書く、さまざまなプログラミング言語が異なってい数据类型基本的な基本的なハオそれは、もちろん、また同じ異なっを持っていませんbyte( ;バイト)それらの一つであり
、我々は最終的にここでは、バイトの形で送信される送信された通信内容の日々の開発、2 例、我々はソースを見てJavaSocket

  • データを送信するためのソケット接続を作成します。
Socket socket = new Socket(ip, port);
OutputStream outputStream = socket.getOutputStream();
//发送数据
outputStream.write("Hello World!".getBytes());
outputStream.flush();
//关闭连接
outputStream.close();
socket.close();
  • 私たちは、見ての機能OutputStreamwirte(byte[] b)
  • OutputStreamの#書き込み(バイト[] b)は
//1 接着又调用了write(byte b[], int off, int len)
public void write(byte b[]) throws IOException {
    write(b, 0, b.length);
}

//2 最后又调用了write(byte b)
public void write(byte b[], int off, int len) throws IOException {
    if (b == null) {
        throw new NullPointerException();
    } else if ((off < 0) || (off > b.length) || (len < 0) ||
               ((off + len) > b.length) || ((off + len) < 0)) {
        throw new IndexOutOfBoundsException();
    } else if (len == 0) {
        return;
    }
    //3 这里就是讲我们发送的一个bye[]进行for循环一个个写入了
    for (int i = 0 ; i < len ; i++) {
        write(b[off + i]);
    }
}

//4 end
public abstract void write(int b) throws IOException;

概要:かどうかは、通信フォーマットの定義は、最終的に変換されるものであるbyte[](字节数组)次のように入力し、限りデータをバイト配列に変換することができて、送信することが数据类型科学の時間を

第三に、バイト数やビットデータ型の数のJavaシェア

データの種類 バイト数 占有ビット数 レンジ
バイト 1 8 -128〜127
CHAR 2 16 '\ U0000' 〜 '\ uFFFF'
ショート 2 16 -2 ^ 15〜2 ^ 15から1
int型 4 32 -2 ^ 31〜2 ^ 31から1
浮く 4 32 2 ^ -149〜2 ^ 128 -1
長いです 8 64 -2 ^ 63〜2 ^ 63から1
ダブル 8 64 2 ^ -1074〜2 ^ 1024から1
ブーリアン / 1 正しいか間違っているか
  • 文字列は、文字は2つのバイトを占有し、Javaでの基本的なデータ型に文字(1バイト)属していません
  • 概要:1バイト= 8ビット

3.1それのビットは何ですか?私の同僚のレベルは何ですか?Javaでは、どのようにコードを書くには?

  • ビットである二进制データ、値のみ01
  • 右に左と下の桁の高
    • ここでは例として、バイト123で:
    • スイッチビットバイトB = 123
    • ハイ0低い1 0111 1011
  • Javaで8ビットバイトの取得
/**
 * byte转8 bit
 *
 * @param b byte
 * @return 高位到低位顺序, 以byte123 为例: 0111 1011
 */
public static byte[] byte2Bit(byte b) {
    byte[] arr = new byte[8];
    for (int i = 7; i >= 0; i--) {
        arr[i] = (byte) (b & 1);
        b = (byte) (b >> 1);
    }
    return arr;
}
  • 8ビットのビットにバイトするので、その後、どのように我々は、その後のバイトに戻ってそれをビットすることができますか?
/**
 * 8个bit位转为byte
 */
public static byte bit2Byte(byte[] bytes) {
    if (bytes.length != 8) return 0;
    String binary = "";
    byte result;
    for (byte b : bytes) {
        binary += b;
    }
    if (bytes[0] == 0) {
        // 正数
        result = (byte) Integer.parseInt(binary, 2);
    } else {
        // 负数
        result = (byte) (Integer.parseInt(binary, 2) - 256);
    }
    return result;
}

3.2お互いにバイト及びビット上に述べてきた、そして今では、ターンでありますint

  • 上に述べてきたint占める4バイト32以上bit
  • 次のようにIntegerクラスは、我々は、ビット転送方式のための良いパッケージを持っています:
String s = Integer.toBinaryString(35235);
//输出结果
1000100110100011
  • あなたは、これが理由ではなく、32を見ることができますか?することで高いので、これはです0ので、直接省略し、もちろん、我々はまた、イニシアチブいっぱい取ることができます32唯一の高い記入位置の必要性を0することができます。
  • 少ししてから戻ってint型へ
int result = Integer.parseInt("1000100110100011", 2);
//输出结果
35235
  • 以下のように、Integer.toBinaryString()負の数をバイナリに変換することができるが、Integer.parseInt(「」、2)負の数は、直接バイナリintに変換することができないことに留意すべきです。
String radix = Integer.toBinaryString(-35235);
System.out.println(radix);
int result = Integer.parseInt(radix, 2);
System.out.println(result);

プログラムの実行が報告されjava.lang.NumberFormatException: For input string:"11111111111111110111011001011101"、その後、どのように我々はint型、それを否定をバックアップします異常?もちろん、次のように、それは方法は、次のとおりです。

//需要借助 BigInteger类
String radix = Integer.toBinaryString(-3535);
BigInteger integer = new BigInteger(radix, 2);
System.out.println(integer.intValue());
//输出结果
-3535

3.3もちろん、我々はコンピュータのバイナリ電卓で計算することができます

私たちは、3.4を超えると述べint占め32バイトで41 byte、当然のことながらint2バイトまたはに変換することができ4、よりbyte以下のように、:

/**
 * 一个int转2个字节的byte数组
 * 由低位到高位的转换
 *
 * @param value
 * @return
 */
public static byte[] intTo2Bytes(int value) {
    byte[] src = new byte[2];
    src[0] = (byte) (value & 0xFF);
    src[1] = (byte) ((value >> 8) & 0xFF);
    return src;
}

/**
 * 一个int转4个字节的byte数组
 * 由低位到高位的转换
 *
 * @param value
 * @return
 */
public static byte[] intTo4Bytes(int value) {
    byte[] src = new byte[4];
    src[0] = (byte) (value & 0xFF);
    src[1] = (byte) ((value >> 8) & 0xFF);
    src[2] = (byte) ((value >> 16) & 0xFF);
    src[3] = (byte) ((value >> 24) & 0xFF);
    return src;
}

ことに留意すべきであるint转byte[]時間である高位数组的0下标または低位数组的0下标上記2つの方法があり、低位在数组的0下标

第四に、たくさん上記BB、そして今、私たちは、特定のプロトコルを介してコンテンツを理解するために来ます

次のように4.1は、合意されました:

ここに画像を挿入説明

次に説明する必要がありucharuintこれはどういう意味?UCHAR = unsigned char型、UINT =符号なし整数、 符号なしデータ、すなわちデータショーであります正数

  • パケット全体は2つの部分から構成されている:分析することができるプロトコルの1、包头+ 扩展数据包、固定ヘッダは32バイトを占める、請求
  • どのように多くの占有内側2は、最初にすべての私たちは、各フィールドのヘッダーを分析する必要があります字节
    • 1バイトUCHAR
    • UINT 4バイト
  • 2、我々は上に集中する必要がどのようにヘッダデータのカプセル化を分析する必要があり、契約によって、我々が見ることができる包头内部次のように、それぞれ、6つのフィールドの合計を含んでいます。
    • 第1の固定されて"DH"、合計を占め2バイト
    • 第二のバージョン1.0の合計を占め、2バイト
    • 拡張のための第3のデータ長"extlen"の合計を占め、4バイト
    • 第四は、拡張データ型である取值0或1の合計を占め、1バイト
    • 5番目のフィールドは、の使用に予約されていない0合計を占め、パディング3バイト
    • 6番目のフィールドは、の使用に予約されていない0合計を占め、パディング20バイト
  • 3、上記の分析によって、食事、我々は簡単に並べ替え、各フィールドアウトバイトによって占有することができます

4.2の話は安いです。私のコードを表示します。

//magic
byte[] magicB = {'D', 'H'};
//协议版本1.0转成int也就是1
byte[] versionB = {0, 1};
//扩展数据长度,这里假定扩展数据的长度为67
byte[] extLenB = intTo4Bytes(67);
//扩展数据类型 0:JSON、1:二进制数据;这里使用JSON
byte[] extType = {0};
//两个保留字段,直接0补齐,上面已经分析了两个字段一共占23个字节
byte[] reserved = new byte[23];
//这里将上面的多个数据合并至一个byte[]
byte[] data = byteMergerAll(magicB, versionB, extLenB, extType, reserved);

ここで、ヘッダデータがうまく処理されている、それはさらにカプセル化することができます

  • 本明細書に記載する方法のためのツールにデータアレイを複数設けます
/**
 * 多个数组合并一个
 *
 * @return
 */
public static byte[] byteMergerAll(byte[]... bytes) {
    int allLength = 0;
    for (byte[] b : bytes) {
        allLength += b.length;
    }
    byte[] allByte = new byte[allLength];
    int countLength = 0;
    for (byte[] b : bytes) {
        System.arraycopy(b, 0, allByte, countLength, b.length);
        countLength += b.length;
    }
    return allByte;
}

4.3カプセル化されたパケットデータ

/**
 * 封装包头数据
 * 固定32个字节,其余的0补齐
 *
 * @param extLen 扩展数据长度
 */
public static byte[] getPkgHead(int extLen) {
    //magic
    byte[] magicB = {'D', 'H'};
    //协议版本1.0转成int也就是1
    byte[] versionB = {0, 1};
    //扩展数据长度,这里假定扩展数据的长度为67
    byte[] extLenB = intTo4Bytes(extLen);
    //扩展数据类型 0:JSON、1:二进制数据;这里使用JSON
    byte[] extType = {0};
    //两个保留字段,直接0补齐,上面已经分析了两个字段一共占23个字节
    byte[] reserved = new byte[23];
    //这里将上面的多个数据合并至一个byte[]
    return byteMergerAll(magicB, versionB, extLenB, extType, reserved);
}

4.4'veは、すでにあなたが今のコマンドを送信できること包頭の契約を述べました

//扩展数据:这里就需要根据实际的文档来生成了,我这里就随便写一个了
String extData = "{\"id\":12,\"cmd\":\"open\"}";
 byte[] extDataB = extData.getBytes();
 //获取包头
 byte[] pkgHead = getPkgHead(extDataB.length);
 //一个完整的数据包
 byte[] sendData = byteMergerAll(pkgHead, extDataB);

ここでハッピーエンドへの完全なパケットは、デバイスとの通信を可能にし、フォーカス:後の部品の数によって、プロトコルの最初の一見を得るために、アカウントの各部分のバイト数、それはローからハイまたはローに高いのですか?

一緒に交換QQグループへようこそ
ここに画像を挿入説明

公開された140元の記事 ウォンの賞賛546 ビュー540 000 +

おすすめ

転載: blog.csdn.net/a_zhon/article/details/91975201