Domanda

Sto implementando il protocollo BitTorent usando Java tramite questa spec . Nella sezione messaggi tutti i messaggi hanno una lunghezza fissa tranne 2; per uno di questi è l'unico messaggio variabile dopo l'handshake, quindi posso controllare gli altri e supporre che sia un messaggio parziale quando nessun altro messaggio si incontra. Ma per il seguente messaggio

bitfield: <len=0001+X><id=5><bitfield>
     

Il messaggio bitfield può essere inviato immediatamente dopo il completamento della sequenza di sincronizzazione e prima che vengano inviati altri messaggi. È facoltativo e non deve essere inviato se un cliente non ha pezzi.

     

Il messaggio bitfield è di lunghezza variabile, dove X è la lunghezza del bitfield. Il payload è un bitfield che rappresenta i pezzi che sono stati scaricati con successo. Il bit alto nel primo byte corrisponde all'indice pezzo 0. I bit eliminati indicavano un pezzo mancante e i bit impostati indicano un pezzo valido e disponibile. I bit di riserva alla fine sono impostati su zero.

     

Un campo bit di lunghezza errata è considerato un errore. I client dovrebbero interrompere la connessione se ricevono campi di bit che non hanno le dimensioni corrette o se il campo di bit ha uno dei bit di riserva impostati.

Non riesco a trovare un modo per analizzarlo se non conosco la lunghezza; come dovrei individuare l'id in un flusso di byte?

Modifica: nel payload del messaggio bitfield sono gli 0 o 1 per ogni pezzo nel file torrent, la lunghezza del messaggio cambierà a seconda della dimensione del contenuto del torrent. Quindi non credo di poter presumere che il numero di pezzi si adatti sempre a un numero di 5 byte.

È stato utile?

Soluzione

Il campo id sarà sempre il 5 ° byte di un messaggio, dopo i quattro byte per il campo len. Puoi fare qualcosa del tipo:

DataInputStream stream;

// ...

int    length  = stream.readInt();
byte   id      = stream.readByte();
byte[] payload = new byte[length - 1];

stream.readFully(payload);

Questo dovrebbe funzionare per qualsiasi messaggio, in realtà, poiché tutti hanno la stessa intestazione <=> + <=>.

Modifica: " Quindi non credo di poter supporre che il numero di pezzi si adatterà sempre in un numero di 5 byte. "

Un campo di lunghezza di quattro byte può gestire fino a 2 ^ 32-1 byte nel payload e con 8 bit per byte che offrono spazio per 34.359.738.360 pezzi. Dovrebbe essere un sacco! : -)

Altri suggerimenti

  

Non riesco a trovare un modo per analizzarlo   se non conosco la lunghezza;

A giudicare dalla descrizione, la lunghezza è indicata nei primi 4 byte del messaggio.

  

come devo individuare l'id in a   flusso di byte?

Sembra che l'id sia il 5 ° byte in ciascun messaggio, subito dopo il campo della lunghezza. Quindi devi solo guardare i primi 5 byte dopo aver finito di analizzare il messaggio precedente.

In precedenza nella specifica a cui facevi riferimento, ho letto: ' Il prefisso di lunghezza è un valore big-endian a quattro byte. '. L'ho letto come: leggi i prossimi quattro byte, convertili in un int e quello dovrebbe essere la tua lunghezza. Se non hai familiarità con il processo di conversione da byte a int, ho usato qualcosa di simile a questo .

Non ho letto le specifiche in dettaglio, ma senza conoscere esplicitamente la lunghezza di un campo di lunghezza variabile o delimitatore di terminazione, non vedo nemmeno come è possibile elaborarlo. Il bitfield=<len=0001+X> non indica forse che ti verrà comunicato della lunghezza (variabile) in anticipo ?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top