Yes here is the code,sorry about the mess I’m hardcoding few things in order to try to get some answer for the peers
peerMsg := PeerMessage{}
peerMsg.Read(conn)
fmt.Println("recv:", peerMsg.Bytes())
assert(peerMsg.Id == 5, "First message must always be os type 5 bitfield")
// We send an interested message
peerMsg = PeerMessage{
Length: 2,
Id: 2,
Payload: make([]byte, 1),
}
_, err = conn.Write(peerMsg.Bytes())
if err != nil {
return err
}
fmt.Println("send:", peerMsg.Bytes())
peerMsg.Read(conn)
fmt.Println("recv:", peerMsg.Bytes())
assert(peerMsg.Id == 1, "Peer always send unchoke")
allPiece := make([]byte, torrent.Info.PieceLength)
// BlockSize = 2**14
// + (BlockSize - 1) rounds up
PieceLength := torrent.Info.PieceLength
if piece == len(piecesHash)-1 {
PieceLength = torrent.Info.Length % torrent.Info.PieceLength
}
fmt.Println(pieceAddress)
fmt.Println("piece lenght:", PieceLength)
var nblocks uint = (uint(PieceLength) + (BlockSize - 1)) / BlockSize
for block := uint(0); block < nblocks; block++ {
length := BlockSize
if (block == nblocks-1) && (uint(PieceLength)%BlockSize != 0) {
length = uint(PieceLength) % BlockSize
}
for {
reqPayload := PieceRequest{}
reqPayload.New(piece, block*BlockSize, length)
peerMsg = PeerMessage{
Length: 13,
Id: 6,
Payload: reqPayload.Bytes(),
}
fmt.Println("send:", peerMsg.Bytes())
_, err = conn.Write(peerMsg.Bytes())
if err != nil {
return err
}
fmt.Println("writed")
peerMsg.Read(conn)
fmt.Println("recv[", block, "]:", len(peerMsg.Bytes()))
copy(allPiece[block*BlockSize:block*BlockSize+length], peerMsg.Bytes())
if peerMsg.Length != 0 {
break
}
}
These are the auxiliar functions.
func (p *PeerMessage) Read(conn net.Conn) error {
header := make([]byte, 4)
_, err := io.ReadFull(conn, header)
if err != nil {
return err
}
length := binary.BigEndian.Uint32(header)
p.Length = length
if length == 0 {
p.Id = 0
p.Payload = nil
return nil
}
body := make([]byte, length)
_, err = io.ReadFull(conn, body)
if err != nil {
return err
}
p.Id = body[0]
p.Payload = body[1:]
return nil
}
func (p *PeerMessage) Bytes() []byte {
var peerMsg bytes.Buffer
buff := make([]byte, 4)
binary.BigEndian.PutUint32(buff, p.Length)
peerMsg.Write(buff)
peerMsg.WriteByte(p.Id)
peerMsg.Write(p.Payload)
return peerMsg.Bytes()
}
func (p *PieceRequest) New(index int, offset uint, length uint) {
p.Index = uint32(index)
p.Begin = uint32(offset)
p.Length = uint32(length)
}
func (p *PieceRequest) Bytes() []byte {
buf := make([]byte, 12)
binary.BigEndian.PutUint32(buf[0:4], p.Index)
binary.BigEndian.PutUint32(buf[4:8], p.Begin)
binary.BigEndian.PutUint32(buf[8:12], p.Length)
return buf
}