Come si può semplificare la conversione dell'ordine di byte di rete da un BinaryReader?


7

System.IO.BinaryReader legge valori in un formato little-endian.

Ho un'applicazione C# che si collega a una libreria di rete proprietaria sul lato server. Il lato server invia tutto in ordine di byte di rete, come ci si aspetterebbe, ma trovo che trattare questo lato client sia scomodo, in particolare per i valori non firmati.

UInt32 length = (UInt32)IPAddress.NetworkToHostOrder(reader.ReadInt32()); 

è l'unico modo che è venuta in mente per ottenere un corretto valore senza segno dal flusso, ma questo sembra sia goffo e brutto, e devo ancora verificare se questo è solo andando a clip fuori alto -ordinare i valori in modo che devo fare cose divertenti su BitConverter.

C'è un modo in cui mi manca mancare di scrivere un involucro attorno al tutto per evitare queste brutte conversioni su ogni lettura? Sembra che ci dovrebbe essere un'opzione di endianità sul lettore per rendere le cose più semplici, ma non ho trovato nulla.

  0

Il codice originale funziona correttamente quando i byte possono rappresentare un intero nativo? 01 ago. 132013-08-01 17:58:30

  0

Non sarà d'aiuto adesso, ma ho creato un [collega ticket] (https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=484149) per BinaryReder/Writer per supportare Bigendian. Vai a votare per questo [qui] (https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=484149). 25 ago. 092009-08-25 13:20:49

5

Nessun convertitore integrato. Ecco il mio involucro (come potete vedere, ho implementato solo la funzionalità di cui avevo bisogno, ma la struttura è abbastanza facile da modificare a proprio piacimento):

/// <summary> 
/// Utilities for reading big-endian files 
/// </summary> 
public class BigEndianReader 
{ 
    public BigEndianReader(BinaryReader baseReader) 
    { 
     mBaseReader = baseReader; 
    } 

    public short ReadInt16() 
    { 
     return BitConverter.ToInt16(ReadBigEndianBytes(2), 0); 
    } 

    public ushort ReadUInt16() 
    { 
     return BitConverter.ToUInt16(ReadBigEndianBytes(2), 0); 
    } 

    public uint ReadUInt32() 
    { 
     return BitConverter.ToUInt32(ReadBigEndianBytes(4), 0); 
    } 

    public byte[] ReadBigEndianBytes(int count) 
    { 
     byte[] bytes = new byte[count]; 
     for (int i = count - 1; i >= 0; i--) 
      bytes[i] = mBaseReader.ReadByte(); 

     return bytes; 
    } 

    public byte[] ReadBytes(int count) 
    { 
     return mBaseReader.ReadBytes(count); 
    } 

    public void Close() 
    { 
     mBaseReader.Close(); 
    } 

    public Stream BaseStream 
    { 
     get { return mBaseReader.BaseStream; } 
    } 

    private BinaryReader mBaseReader; 
} 

In sostanza, ReadBigEndianBytes fa il lavoro sporco, e questo viene passato a un BitConverter. Ci sarà un problema preciso se si legge un numero elevato di byte poiché ciò causerà una grande allocazione di memoria.

  0

Nota: Array . Reverse() invertirà l'ordine della matrice sul posto. 24 giu. 162016-06-24 15:59:05


1

Ho creato un BinaryReader personalizzato per gestire tutto questo. È disponibile come part of my Nextem library. Ha anche un modo molto semplice per definire le strutture binarie, che credo ti aiuteranno qui: dai un'occhiata agli esempi.

Nota: è solo in SVN adesso, ma molto stabile. Se hai qualche domanda, scrivimi a cody_dot_brocious_at_gmail_dot_com.

  0

Grazie. Speravo in un certo senso di evitare di prendere in mano una dipendenza aggiuntiva dalla libreria, dato che l'intera faccenda in realtà dovrebbe essere abbastanza piccola e semplice, ma lo terro in considerazione. Però è bello vedere che la licenza è inequivocabile. :) 23 set. 082008-09-23 21:37:03

  0

Ah, capisco. Bene, spero che funzioni per te se decidi di seguirlo. E sì, sono diventato di dominio pubblico proprio per questo motivo - voglio che le persone siano in grado di fare assolutamente tutto ciò che vogliono con esso, e le componenti sono abbastanza piccole da non avere problemi di patch back :) 23 set. 082008-09-23 21:39:34