A análise de uma mensagem de comprimento variável
-
06-07-2019 - |
Pergunta
Estou implementando o protocolo BitTorrent usando Java através deste especificação . Na seção de mensagens de todas as mensagens são comprimento fixo, exceto 2 deles; para um deles é a única mensagem variável após o aperto de mão que eu possa verificar outros e assumir que é uma mensagem peça quando há outras mensagens atendidas. Mas para a seguinte mensagem
bitfield: <len=0001+X><id=5><bitfield>
A mensagem bitfield só pode ser enviada imediatamente após a seqüência de negociação está concluída, e antes de quaisquer outras mensagens são enviadas. É opcional e não precisa ser enviado se um cliente não tem peças.
O campo de bits de mensagem é de comprimento variável, em que X é o comprimento do campo de bits. A carga útil é um campo de bits representando as peças que foram baixados com sucesso. O bit mais alto nos primeiros bytes corresponde ao índice peça 0. Os bits que são apuradas indicou uma peça em falta, e conjunto de bits indicam um pedaço válidos e disponíveis. Peças pedaços no final estão definidas para zero.
A bitfield do comprimento errado é considerado um erro. Os clientes devem cair a conexão se receberem bitfields que não são do tamanho correto, ou se o bitfield tem qualquer do conjunto de bits de reserva.
Eu não posso chegar a uma maneira de analisá-lo se eu não sei o comprimento; como vou para localizar id em um fluxo de bytes?
Edit: Na carga útil da mensagem bitfield é o 0 ou 1 de para cada peça no arquivo torrent, comprimento da mensagem vai mudar, dependendo do tamanho do conteúdo torrent. Então eu não acho que eu posso supor que o número de peças irá sempre se encaixam em um número 5 byte.
Solução
O campo id
será sempre o 5º byte de uma mensagem, após os quatro bytes para o campo len
. Você pode fazer algo como o seguinte:
DataInputStream stream;
// ...
int length = stream.readInt();
byte id = stream.readByte();
byte[] payload = new byte[length - 1];
stream.readFully(payload);
Isso deve funcionar para qualquer mensagem, na verdade, uma vez que todos têm o mesmo len
+ cabeçalho id
.
Editar: "Então eu não acho que eu posso supor que o número de peças irá sempre se encaixam em um número 5 byte"
Um campo de comprimento de quatro bytes pode suportar até 2 ^ 32-1 bytes na carga útil, e com 8 bits por byte que lhe dá espaço para 34,359,738,360 peças. Isso deve ser suficiente! : -)
Outras dicas
Eu não posso chegar a uma maneira de analisá-lo se eu não sei o comprimento;
Julgando a partir da descrição, o comprimento é determinado nos primeiros 4 bytes da mensagem.
Como é que eu vou para localizar id em um fluxo de bytes?
Parece que o id é o 5º byte em cada mensagem, logo após o campo de comprimento. Então você só tem que olhar para os primeiros 5 bytes após terminar analisar a mensagem anterior.
No início da especificação você referenciou, eu li: ' O prefixo comprimento é um valor grande-endian quatro bytes .'. Eu li que, como: ler em seguida quatro bytes, convertê-los para um int, e que deve ser o seu comprimento. Se você não estiver familiarizado com o processo de int conversão bytes-to-, eu tenho algo usado similar a este .
Eu não li a especificação em detalhes, mas sem saber quer explicitamente o comprimento de um campo de comprimento variável ou algum delimitador de rescisão, não vejo como você pode processá-lo também. Será que o bitfield=<len=0001+X>
não talvez indique que você ser dito do (variável) comprimento up-front ?