2017-07-18 4 views
-1

Le problème: J'ai besoin de mettre en œuvre un lecteur d'entrée réseau à partir d'un dispositif électronique qui a des définitions fixes d'un format de paquet. Il a un en-tête, un pied de page et un corps de données. Les champs du paquet sont définis en terme de bits.Sérialisation et désérialisation personnalisées Java avec des définitions de taille de bit

Exemple: La variable sequence_number de champ est les bits numérotés 8-31 et ack_status est peu 32. Comment puis-je créer une fonction de sérialisation personnalisée afin que je puisse convertir un objet Java et d'un octet [] lire d'un paquet?

Dans un 32 bits Packet

StartOfPacketHeader 4bits

CommandCode 4bits

SequenceNumber 23bits

AckStatus 1 bit

Comment puis-je faire une classe wrapper Java pour cet objet avec un constructeur byte [] et une méthode toBytes().

L'utilisation de l'interface sérialisable n'a aucun contrôle sur les tailles de données individuelles. Les tailles de données peuvent être des valeurs impaires comme une variable de 3 bits ou de 18 bits. Je ne peux pas spécifier la longueur des variables en termes de bits.

Ce que je l'ai fait jusqu'à présent:

La source envoie effectivement des entiers non signés, ce qui signifie le type Java int ne peut pas gérer toute sa gamme. J'ai besoin de définir tous les types de données aussi longtemps pour gérer tous les cas. J'ai utilisé la classe BitSet pour effectuer byte [] en conversion longue, mais c'est trop fastidieux et déroutant car bitset inverse l'ordre des bits à Little Endian par défaut.

Résumé:

Comment puis-je convertir à mon objet à partir des octets [] Je lis à partir du réseau et vice versa avec les définitions personnalisées pour chaque champ de la manière la plus efficace?

Répondre

0

Vous utilisez DataInputStream et DataOutputStream pour cela, avec un BufferedInputStream ou BufferedOutputStream sous eux respectivement à des fins d'efficacité. Les champs de bits que vous devrez programmer vous-même, mais ces classes fournissent toutes les primitives Java dans l'ordre des octets du réseau.

Pour le paquet que vous avez publié, vous avez besoin quelque chose comme ceci:

class Packet 
{ 
    private byte header; 
    private byte commandCode; 
    private int  sequenceNumber; 
    private boolean ackStatus; 

    void write(DataOutput out) throws IOException 
    { 
     int wirePacket = header|(commandCode << 4)|(sequenceNumber << 8); 
     if (ackStatus) 
     { 
      wirePacket |= 0x80000000; 
     } 
     out.writeInt(wirePacket); 
    } 

    static Packet read(DataInput in) throws IOException 
    { 
     Packet packet = new Packet(); 
     int wirePacket = in.readInt(); 
     packet.header = (byte)(wirePacket & 0x0f); 
     packet.commandCode = (byte)((wirePacket >>> 4) & 0x0f); 
     packet.sequenceNumber = (wirePacket >>> 8) & 0x7FFFFF; 
     packet.ackStatus = (wirePacket & 0x80000000) != 0; 
     return packet; 
    } 
    // getters and setters. The setters must ensure that the values don't go out of range. 
} 
+0

Pouvez-vous citer un exemple? –

+0

Pourquoi? Tu ne peux pas lire le Javadoc? – EJP

+0

J'ai besoin de la logique? Je sais déjà comment les utiliser –