I’m stuck on stage #nd2
.
To implement downloading the mentioned piece, I am basically creating a struct called Peer
that handles all the communication with a remote peer. On its instantiation, it performs the handshake, waits for a bitfield message, sends an interested message, and then waits for an unchoke message.
After all this process is complete, it then makes requests for all the blocks of the pieces, and then registers a global handler that reads messages from the peer connection, and if it’s a piece message, then handles it appropriately.
I am puzzled by the invalid message codes that I am receiving. I am accounting for empty keep alive messages as well, but still no luck.
Here are my logs:
remote: [tester::#ND2] Running tests for Stage #ND2 (Download a piece)
remote: [tester::#ND2] Running ./your_program.sh download_piece -o /tmp/torrents3482308911/piece-9 /tmp/torrents3482308911/itsworking.gif.torrent 9
remote: [your_program] [165.232.38.164:51548] Initializing handshake
remote: [your_program] [165.232.38.164:51548] Handshaking completed
remote: [your_program] [165.232.38.164:51548] Recieved bitfield message
remote: [your_program] [165.232.38.164:51548] Sent interested message
remote: [your_program] [165.232.38.164:51548] Recieved unchoke message
remote: [your_program] [165.232.38.164:51548] sent request message for piece_idx = 9, block_idx = 2
remote: [your_program] [165.232.38.164:51548] sent request message for piece_idx = 9, block_idx = 0
remote: [your_program] [165.232.38.164:51548] sent request message for piece_idx = 9, block_idx = 1
remote: [your_program] [165.232.38.164:51548] sent request message for piece_idx = 9, block_idx = 6
remote: [your_program] [165.232.38.164:51548] sent request message for piece_idx = 9, block_idx = 3
remote: [your_program] [165.232.38.164:51548] sent request message for piece_idx = 9, block_idx = 4
remote: [your_program] [165.232.38.164:51548] sent request message for piece_idx = 9, block_idx = 5
remote: [your_program] [165.232.38.164:51548] sent request message for piece_idx = 9, block_idx = 8
remote: [your_program] [165.232.38.164:51548] sent request message for piece_idx = 9, block_idx = 7
remote: [your_program] [165.232.38.164:51548] sent request message for piece_idx = 9, block_idx = 9
remote: [your_program] [165.232.38.164:51548] sent request message for piece_idx = 9, block_idx = 10
remote: [your_program] [165.232.38.164:51548] sent request message for piece_idx = 9, block_idx = 11
remote: [your_program] [165.232.38.164:51548] recieved piece message for piece_idx = 9, begin_idx = 2, block_len = 16384
remote: [your_program] [165.232.38.164:51548] recieved message with ID = 1, expected PIECE_MESSAGE_ID = 7
remote: [your_program] [165.232.38.164:51548] recieved message with ID = 204, expected PIECE_MESSAGE_ID = 7
remote: [tester::#ND2] timed out, test exceeded 10 seconds
remote: [tester::#ND2] Test failed
remote:
My best guess would be that the way I am using the RecieveMessage
is incorrect, but I don’t see anything wrong with it out of the box:
// RecieveMessage reads a message from the peer.
// It first reads the 4-byte length prefix, then reads the message of that length.
func (p *Peer) RecieveMessage() ([]byte, error) {
lengthPrefix := make([]byte, 4)
_, err := p.conn.Read(lengthPrefix)
if err != nil {
return nil, fmt.Errorf("error reading message length: %v", err)
}
length := binary.BigEndian.Uint32(lengthPrefix)
// Keep-alive message, so recursively call itself
if length == 0 {
return p.RecieveMessage()
}
message := make([]byte, length)
_, err = p.conn.Read(message)
if err != nil {
return nil, fmt.Errorf("error reading message body: %v", err)
}
return message, nil
}
Here is all of my code, anyway, if it helps. Would appreciate any pointers or gotcha’s that I might not be handling properly.