まず、起源
Androidのニーズは、多くの場合、ボード、対話するスマートデバイスの様々なプログラムで遭遇も、基本的な方法を伝える仕事Ble
やSocket tcp/udp
その最も重要なことはコミュニケーションがあるに... 协议
、协议
、协议
その3倍を言うことが重要です。このようなデータパケットとして、デバイスとの相互作用の方法と相互作用する通信プロトコルの形式を定義するために使用されます。(包头—数据包长度—数据—校验位—包尾)
第二に、バイト数によって占められるように、各種データを管理する第一のプロセッサ
1、我々は最終的に、バイナリまたはバイトコードによって識別することができ、様々なマシンに変換するコードを書く、さまざまなプログラミング言語が異なってい数据类型
基本的な基本的なハオそれは、もちろん、また同じ異なっを持っていませんbyte
( ;バイト)それらの一つであり
、我々は最終的にここでは、バイトの形で送信される送信された通信内容の日々の開発、2 例、我々はソースを見てJava
Socket
- データを送信するためのソケット接続を作成します。
Socket socket = new Socket(ip, port);
OutputStream outputStream = socket.getOutputStream();
//发送数据
outputStream.write("Hello World!".getBytes());
outputStream.flush();
//关闭连接
outputStream.close();
socket.close();
- 私たちは、見ての機能
OutputStream
wirte(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では、どのようにコードを書くには?
- ビット
位
である二进制
データ、値のみ0
、1
- 右に左と下の桁の高
- ここでは例として、バイト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
バイトで4
1 byte
、当然のことながらint
2バイトまたはに変換することができ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は、合意されました:
次に説明する必要があり
uchar
、uint
これはどういう意味?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
バイト
- 第1の固定されて
- 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グループへようこそ