Frage

Ich versuche, eine Hex-Nachricht von einem C-Server an einen Java-Client zu übergeben.Die Kommunikation funktioniert.Aber der Hexadezimalwert, den ich auf dem Java-Client erhalte, scheint mit „ff“ angehängt zu sein.Warum passiert das?

Wenn ich auf der C-Seite die Bytes ausdrucke, die ich senden möchte (in Hex), scheinen sie in Ordnung zu sein.

Bitte sehen Sie sich den folgenden Code an:

C-Server:

                    int datalen = 220;

                    /* create  outgoing message */
                    idx = 0;
                    en_outmsg[idx++] = FEB & 0xFF;
                    en_outmsg[idx++] = ENT & 0xFF;
                    en_outmsg[idx++] = CBA & 0xFF;
                    en_outmsg[idx++] = GRP & 0xFF;
                    en_outmsg[idx++] = OUTGOING & 0xFF;
                    en_outmsg[idx++] = (datalen & 0xFF00) >> 8;
                    en_outmsg[idx++] = datalen & 0xFF;

                    for(i= 0; i<39; i++){
                    printf("en_outmsg[%d] to send = %x\n",i, en_outmsg[i]);
                    }
                    en_outmsg[i+1] = '\n';


                    if (send(connected, en_outmsg, 40, 0) > 0)
                    {
                        printf("sending over\n");

                    }

Java-Client:

    while( (bytes =dis.read(buffer, 0, 40)) != -1){
        for(int index=38; index >= 0; index--)  {           

                System.out.println("index ="+index);
                System.out.println("buffer ="+Integer.toHexString(buffer[index]));
        }
        System.out.println("bytes="+bytes); 
        len = 0;
        len |= buffer[5];
        len = len << 8;
        len |=  buffer[6];
        System.out.println("value of len= "+len);
    }

Ausgabe:Wert von len= -36 buffer[5]=0 buffer[6]= 0xfffffffdc

AKTUALISIERT

Hier ist meine Wireshark-Ausgabe (Dies ist, was der C-Server an den Java-Client überträgt):

Beachten Sie, dass in Zeile 5 „00 dc“ datalen= 220 entspricht, das als solches in len auf dem Java-Client gespeichert werden sollte.Es liegt also eindeutig ein Fehler im Java-Client vor.Wie Sie alle erwähnt haben, kann ich Integer.toHexString(((int)buffer[index]) & 0xFF) zum Drucken verwenden.Aber ich muss das Byte-Array mit den richtigen Hex-Werten speichern.Bitte helfen Sie

0000  00 00 03 04 00 06 00 00  00 00 00 00 00 00 08 00   ........ ........
0010  45 00 00 5c b4 75 40 00  40 06 a0 ac c0 a8 b2 14   E..\.u@. @.......
0020  c0 a8 b2 14 09 60 b7 bb  fe bd 3a 2d fe 36 cc 8c   .....`.. ..:-.6..
0030  80 18 02 20 e5 c8 00 00  01 01 08 0a 00 04 8e 5f   ... .... ......._
0040  00 04 8e 5f 0a 01 01 16  01 00 dc 00 01 02 03 04   ..._.... ........
0050  05 06 07 08 09 0a 0b 0c  0d 0e 0f 2b 7e 15 16 28   ........ ...+~..(
0060  ae d2 a6 ab f7 15 88 09  cf 4f 3c d0               ........ .O<.    
War es hilfreich?

Lösung

Ihr erster Schritt in dieser Situation sollte darin bestehen, zu sehen, was „über das Kabel“ gesendet wird.Wenn Sie dazu in der Lage sind, sollten Sie die Verwendung in Betracht ziehen wireshark oder tcpdump um zu sehen, was übertragen wird.Auf diese Weise können Sie herausfinden, was nicht wie erwartet funktioniert.Beide können sowohl an lokale IPs gebundene Sockets als auch Loopback-Sockets überwachen.

Aber so wie es aussieht, würde ich zustimmen, dass es einen Konflikt zwischen unterzeichneten und nicht unterzeichneten Personen gibt.

Wenn Sie über diese Ausgabe verfügen, wäre dies hilfreich, um festzustellen, wer die Schuld trägt.

Aktualisieren:

Wie bereits erwähnt, möchten Sie die niedrigsten 8 Bits maskieren und nur verwenden. Dies kann wie folgt erreicht werden:

b = b & 0xFF

Sie können dies auf zwei Arten in Ihren Code integrieren: Zum einen über eine einfache statische Funktion, die Sie für jedes Byte aufrufen würden, z. B.

public static int mask(int rawbyte)
{
    return (rawbyte & 0xFF);
}

Die andere ist eine Wrapper-Funktion für DataInputStream.read(), die die Bytes in einen Puffer einliest und sie dann alle maskiert.Es könnte etwa so aussehen:

public static int socket_read(DataInputStream dis, int arr[], int off, int len)
{
    b = new byte[len];
    int rv = dis.read(b, off, len);
    for(int i=0; i < len; i++)
    {
        arr[i] = ((int)b[i]) & 0xFF;
    }
    return rv;
}

Wenn Sie sich für den ersten Weg entschieden haben, möchten Sie mask() für jeden von Ihnen verwendeten buffer[]-Wert aufrufen.Also

len |= buffer[5];

wäre

len |= mask(buffer[5]);

Wenn Sie den zweiten Weg wählen würden, würden Sie den Puffer von einem Array vom Typ Byte in Int ändern:

buffer = new int[...]

und könnte Ihre while-Schleife auf etwas wie Folgendes aktualisieren:

while( (bytes = socket_read(dis, buffer, 0, 40)) != -1)

Aber abgesehen davon...

Eine bessere Option als beides ist die Nutzung von Die readUnsignedByte-Methode von DataInputStream.

Sie müssten selbst 40 Bytes auf einmal aus dem Stream ziehen, aber es wäre viel klarer, was Sie tun, als etwas herumzuspielen.Dies wäre meiner Meinung nach der bevorzugte Ansatz.

Andere Tipps

Die Bytes in Java sind signiert.Jeder Wert, für den das höchstwertige Bit gesetzt ist, ist also ein negativer Wert.Wenn es in eine Ganzzahl konvertiert wird, die beim Aufrufen von Integer.toHexString auftritt, wird das Vorzeichen erweitert.Wenn es also 10000000b war, wird es 1111111111111111111111110000000b oder 0xFFFFFF80 anstelle von 0x80.Denn das ist der gleiche negative Wert in 32 Bit.Tun

Integer.toHexString(((int)buffer[index]) & 0xFF)

Sollte das Problem beheben.

Übrigens hat Java keine vorzeichenlosen Typen.

But the hex value that I get on Java client seems to be appended with "FF"

Integer.toHexString(buffer[index] & 0xFF ) behebt Ihr Problem.

Klingt nach Vorzeichenbitausbreitung.len und andere JAVA-Variablen sehen wie signiert aus, wenn sie nicht sollten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top