3

符号なしバイトの配列を利用する必要があります。ネットワークを介して特定の文字をサーバーに送信する必要がありますが、これらの文字の一部は127を超えています。

概念を理解するために、以下のコードの簡略化されたバージョンがあります。

int i= 160;
byte j = (byte) i;
System.out.println((byte)i);
System.out.println(j);

これにより、次の出力が得られます。 -96 -96

160を出力する必要があります。サーバーは160のバイトを予期しており、-96を受信した場合、値を受け入れません。私がintを使用した理由は、問題を回避する方法を読んでいるときに、intを使用するという提案に出くわすことがよくありましたが、配列がbyte型である必要があるため、よくわかりません。 。

これは、配列を送信するコードの一部です。

public boolean send(byte[] data) {
    try {
     out.write(data); // Write the data to the outStream
     out.flush();
    } catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false; // Return false if the TCP Transmit failed 
// }
return false;
}

誰かが私を助けてくれたら本当にありがたいです。

4

4 に答える 4

10

Javaでは、符号付きバイトと符号なしバイトの区別はありません。次の両方が同じ値をバイトに割り当てます。

byte i = (byte)160;
byte j = (byte)-96;

それらを印刷するときに署名付きまたは署名なしとして扱うのは、開発者としてのあなた次第です。デフォルトでは、それらを符号付きで印刷しますが、符号なしの方法で整数に変換することにより、それらを強制的に符号なしで印刷することができます。

System.out.println(i); // -96
System.out.println(0xff&i); // 160

バイトが負の数と正の数の両方を同時に表す方法を知りたい場合は、Javaでの2の補数演算に関するこの記事を読んでください。

于 2013-02-25T18:19:59.143 に答える
2

-96の送信は正しい動作です。符号付きバイトと符号なしバイトは、印刷されるときは異なりますが、ビット表現では異なります。また、別のサーバーで受信されたときに違いが生じることはありません。

于 2013-02-25T18:20:02.233 に答える
2

System.out.println(byte)はありません。最も近いのはSystem.out.println(int)です。これは、バイト値がintに変換されることを意味します。変換により上位ビットが拡張され、負の数になります。

この次のコードは私のポイントを示しています:

byte[] data =
{
    (byte)0x01,
    (byte)0x02,
    (byte)0x7F,
    (byte)0x80
};

for (byte current : data)
{
    String output = String.format("0x%x, 0x%x", current, (int)current);
    System.out.println(output);
}

System.out.printlnを使用してバイト値を確認する場合は、次のように、整数値の上位3バイトをマスクします。

System.out.println(((0x000000FF & (int)current);
于 2013-02-25T18:31:44.537 に答える
1

バイトは、それ自体で符号付きまたは符号なしではありません。一部の操作が適用されると、それらはそのように解釈されます(たとえば、0と比較して符号を決定します)。演算は符号付きと符号なしが可能であり、Javaでは符号付きバイト演算のみが使用可能です。したがって、引用したコードは質問には役に立ちません。バイトを送信しますが、操作は行いません。バイトを受け取るコードをより適切に表示します。正しくて便利な方法の1つはjava.io.InputStream.read()、0〜255の範囲の整数としてバイトを返すメソッドを使用することです。

于 2013-02-25T18:26:15.457 に答える