ffffff @ DatagramSocket.receive

A

Andi_K

Gast
Hallo zusammen,

ich bin gerade dabei ein kleines Tool zu schreiben womit ich zum einen eine serielle Verbindung und UDP Pakete abhöhren kann.

Für die serielle Verbindung nutze ich RXTX. Um an die UDP Pakete zu kommen nutze ich java.net.*.

Mein Tool funktioniert soweit gut. Ich bekomme die seriellen Daten und die UDP Pakete.
Mir ist jetzt allerdings aufgefallen, dass ich bei manchen Daten, sowohl seriell als auch bei den UDP Paketen ein negatives Byte habe, was sich im Hexcode mit einem 'ffffff<hexzeichen>' auswirkt.

Hat jemand eine Ahnung an was das liegt?

Bei der seriellen Verbindung ist mir das auch schon aufgefallen. Dort habe ich einfach den String überprüft. Wenn er mti 'ffffff' anfängt, habe ich die 'ffffff' einfach weggeschnitten.
Mich wundert es aber trotzdem woher die 'ffffff's kommen.

Hier mal der Code um die UDP Daten zu lesen:

Code:
public static void ResceivePort(int port) throws java.io.IOException 
    {
        int n = 0;
        DatagramSocket  serverSocket = new  DatagramSocket(port);     // Serversocket mit bestimmter Port-Nummer erstellen
        byte[] receiveData = new byte[1024];
        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        do
        {
            
            serverSocket.receive(receivePacket);


            int i = 0;
            // Lese die nächsten 10 Frames mit
            do
            {
                //System.out.println(receivePacket.getData().length);
                if (Integer.toHexString(receivePacket.getData()[i]).length()==1)
                {
                    System.out.print("0" + Integer.toHexString(receivePacket.getData()[i]) + ":");
                }
                else
                {
                    System.out.print(Integer.toHexString(receivePacket.getData()[i]) + ":");
                }

                i++;
            }while(receivePacket.getData().length > i);
            System.out.println("");
            n++;
        }while(n<10);
    }

Also danke für die Hilfe.

Gruß
Andi
 
A

Andi_K

Gast
Aso ganz vergessen.
So sieht zum Beispiel der Anfang von einem Frame aus:
Code:
00:2d:53:33:00:00:00:00:01:00:00:00:01:00:65:00:ffffffb1:50:00:00:44:41:54:31:3a:30:0a:44:41:54:32:3a
Interessant ist, dass das 'ffffff' Stück immer an der gleichen Stelle ist. Die b1 ist ansonsten schon korrekt.

Gruß
Andi
 
N

nillehammer

Gast
In Java sind Bytes vorzeichenbehaftet. Sprich alle Bytes, in deren erstem Bit eine 1 ist, werden als negativ betrachtet (Stichwort. Zweier-Komplement). Die Methode Integer.toHexString castet das byte nach int hoch. Damit beim Casten das Vorzeichen erhalten bleibt und der Betrag stimmmt, werden alle führenden Bits im int mit 1 gefüllt (wieder Stichwort: Zweier-Komplement). Das siehst Du dann als "ffffff". Soweit die Erklärung für Deine Ausgabe. Warum vom Socket negative Bytes kommen, ob sie kommen sollen, ob der Sender sie überhaupt als negativ ansieht oder ähnliches, hängt von Deinem konkreten Anwendungsfall ab.
 
Zuletzt bearbeitet von einem Moderator:

HoaX

Top Contributor
Statt
Java:
if (Integer.toHexString(receivePacket.getData()[i]).length()==1)
                {
                    System.out.print("0" + Integer.toHexString(receivePacket.getData()[i]) + ":");
                }
                else
                {
                    System.out.print(Integer.toHexString(receivePacket.getData()[i]) + ":");
                }

kannst du auch gleich
Java:
System.out.printf("%02x\n", receivePacket.getData()[i]);
schreiben. Drei mal toHexString mit dem selben Parameter aufrufen ist doch ekelhaft/unnötig.

Ansonsten sei noch gesagt, dass du auch
Java:
int i = 0xff & receivePacket.getData()[i];
machen kannst, um das byte ohne Vorzeichen in einen int umzuwandeln.
 
A

Andi_K

Gast
Hallo zusammen,

danke für die Erklärung. Warum ich ein negatives Byte bekomme ist mir zwar unklar, da mein UDP Frame eigendlich nur positive Frames enthält(Mit Wireshark verglichen).

Mit 0xff funktioniert es super.

Code:
if (Integer.toHexString(receivePacket.getData()[i]).length()==1)
{
    System.out.print("0" + Integer.toHexString(receivePacket.getData()[i]) + ":");
}
else
{
     System.out.print(Integer.toHexString(receivePacket.getData()[i]) + ":");
}

War nur zum testen. Ich übergebe den int Wert eh einer anderen Funktion, die ihn dann direkt in Ascii umwandelt.
Also vielen Dank für die Hilfe.
 

HoaX

Top Contributor
Nochmal zum Negativen: Wenn du z.B. 255 sendest, dann ist das binär 11111111. In Java ist byte aber immer mit Vorzeichen, darum kommt dann bei Java -1 heraus. Ein Byte in Java kann keinen Wert > 127 annehmen, sondern es findest nach 127 der überlauf zu -128 statt. Wenn du nun Integer.toHexString aufrufst wird das Byte automatisch in einen Integer umgewandelt, und aus 11111111 (-1 als byte) wird 11111111111111111111111111111111 (-1 als int). Darum die vielen "ff". Durch dass & 0xff werden die ersten 24 Bit vom Integer auf 0 gesetzt, und nur die letzten 8 Bit so übernommen wie sie stehen -> Es kommt wieder 11111111 heraus, aber diesmal eben als Integer, der ist nun nicht negativ, und entspricht daher wieder 255 (dezimal).
 
Ähnliche Java Themen

Ähnliche Java Themen


Oben