Qual è il metodo migliore per identificare gli oggetti in un array di byte?

0

Ho letto byte da un socket. I dati sono costituiti solo da due tipi di strutture:

struct A
{
    unsigned char type_id;        //0x01
    unsigned char sequence_id;    //Incremented in successive packets.
    //Some other fields

    unsigned char checksum;
};

struct B
{
    unsigned char type_id;        //0x02
    unsigned char sequence_id;    //Incremented in successive packets. This sequence is independent from A's sequence_ids.
    //Some different fields

    unsigned char checksum;
};

Queste strutture sono scritte sul filo senza particolari schemi di come si presentano. Questi sono gli unici dati che ricevo. Posso leggere i dati.

Sto cercando di capire come meglio identificare questi pacchetti nell'array unsigned char* che ho letto. In questo momento sto iterando finché non trovo i byte 0x01 o 0x02 e poi in base alla dimensione della struttura rilevante, prova ad ottenere la struttura successiva. Una volta stabilito che ho trovato un confine di pacchetti, continuo a compensare di sizeof(A) o sizeof(B) di conseguenza e spero di star bene.

Il mio problema è che se c'è un valore 0x01 o 0x02 in un campo all'interno di una struct stessa quando sto verificando l'inizio di una struct, questo metodo restituirebbe strutture non valide.

Purtroppo non riesco a toccare il lato server. È piuttosto un vecchio sistema.

Un altro punto è che mi unisco come client a metà strada, cioè, il lato server continua a inviare dati - questo significa che il primo byte che ho letto la maggior parte delle volte non è l'inizio di un pacchetto.

Che cosa posso fare per identificare le strutture in modo efficace?

    
posta nakiya 02.06.2017 - 10:55
fonte

1 risposta

3

Qualsiasi type_id valido è un inizio pacchetto possibile , ma hai due campi aggiuntivi che possono verificare se questo è il caso:

  • Per tutti tranne il primo pacchetto, è possibile confrontare il numero di sequenza. Se non corrisponde, hai sbagliato e dovresti continuare a cercare il prossimo possibile avvio del pacchetto. Ciò richiederebbe il buffer fino almeno al secondo pacchetto mentre si stabilisce una connessione client.

  • Una volta letto un pacchetto, puoi confrontare il checksum. Se non corrisponde, elimina il pacchetto e cerca il prossimo avvio possibile.

Ovviamente questo diventa meno utile più id di tipo ci sono, perché i simboli di avvio potrebbero essere molto frequenti. Ciò non rende impossibile l'approccio di cui sopra, ma è più costoso in quanto è necessario testare l'avvio di un pacchetto più spesso.

A seconda delle dimensioni dei dati e dell'algoritmo del checksum, anche un checksum a 8 bit è estremamente sottile. Per esempio. se i byte sono solo XORed l'uno con l'altro, mi aspetterei troppi falsi positivi perché ciò sia fattibile.

Se si utilizzano effettivamente "socket" come in "socket TCP", è garantito che i dati arrivino incorrotti, il che significa che il checksum non può mai essere non valido e può essere utilizzato per rilevare i limiti del pacchetto. Ma in quel caso, sarebbe anche impossibile ricevere mezzo pacchetto.

Se si sta effettivamente ascoltando una trasmissione su un supporto pubblico (ad esempio radio), di solito sono in vigore protocolli che consentono la sincronizzazione, ad es. una frequenza portante. Per la trasmissione dei dati, può essere utilizzato anche un simbolo di avvio (syncword, carattere di sincronizzazione, preambolo) che non può essere presente nel messaggio stesso. Ad esempio, Ethernet ha un Delimitatore frame iniziale. In generale, dare un'occhiata ai protocolli del livello di collegamento dati potrebbe essere illuminante per vedere come questi problemi di sincronizzazione vengono risolti nella pratica, anche se molti protocolli come Ethernet devono anche gestire il problema di mittenti multipli che non si applica nel tuo caso.

    
risposta data 02.06.2017 - 11:27
fonte

Leggi altre domande sui tag