views:

293

answers:

4

Two quotes:

All of the remaining messages in the protocol take the form of <length prefix><message ID><payload>. The length prefix is a four byte big-endian value. The message ID is a single decimal byte. The payload is message dependent.

request: <len=0013><id=6><index><begin><length>

The request message is fixed length, and is used to request a block. The payload contains the following information:

  • index: integer specifying the zero-based piece index
  • begin: integer specifying the zero-based byte offset within the piece
  • length: integer specifying the requested length.

When I write everything it sums up to 5 bytes. Using

ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
byteStream.write( 13 );
byteStream.write( 6 );
byteStream.write( index );
byteStream.write( begin );
byteStream.write( length );

message = byteStream.toByteArray();

EDIT: Sorry i was kind of pissed when i wrote it. its the bittorent protocol. Using this spec.

+1  A: 

write() writes bytes. 5 write()'s produces 5 bytes.

mamboking
+5  A: 

The write() method writes one byte.

If you send it a char or int it just strips everything above the 8th bit with & 0xFF.

You have more options with DataOutputStream (writeInt, writeShort etc.) but it uses big endian byte order so you might need to perform an Integer.reverseBytes() (or Short.reverseBytes()) call before passing in the value to the writeXYZ() method.

ByteArrayOutputStream byteStream = new ByteArrayOutputStream();

DataOutputStream dout = new DataOutputStream(byteStream);

dout.writeInt( 0x13 ); // L:4
dout.write( 6 ); // L:5
dout.writeShort( index ); // guess, L:7
dout.writeLong( begin ); // >4GB support? L:15
dout.writeInt( length ); // clients accept below to 2^17, L:19

dout.flush(); // to be sure

message = byteStream.toByteArray();

Remark: The spec doesn't state the length of index, begin and length. I just wanted to give a sample of the available options.

Edit 2: Edited the sample based on D.Shawley's answer and a spec found here.

kd304
In the OP, he says he is using big-endian too.
Matthew Flaschen
For the length prefix only.
kd304
+1  A: 

See write(int b).

Writes the specified byte to this output stream. The general contract for write is that one byte is written to the output stream. The byte to be written is the eight low-order bits of the argument b. The 24 high-order bits of b are ignored.

Subclasses of OutputStream must provide an implementation for this method.

Parameters: b - the byte.

eed3si9n
+2  A: 

I'm not sure what you are getting at here... the quoted text doesn't say what the length of <index>, <begin>, or <length> is. The first quote states, rather clearly, that a message consists of a 4-byte length, followed by a 1-byte identifier, and an arbitrary payload.

The length of the payload is probably either the value specified as <length> or <length>+5 depending on exactly what <length> means. The second quote looks like the definition of whatever message is identified by the 1-byte identifier of 0x06. I would guess that:

  1. the payload, the bytes that make up <index><begin><length>, is probably 14 bytes long
  2. the length is being displayed in hex so 0x0013 is 19 decimal

In any case, the byte stream that you are generating does not seem to match the message definition AND the message definition lacks clarity.

D.Shawley
The quote I think is describing a binary protocol over some network.
eed3si9n