Ejemplo n.º 1
0
        private static int GetIndexOfNextPieceAvaivable(Peer peer, FileSavingController fileSavingController)
        {
            int index;

            do
            {
                index = peer.IndexOfNextAvaivablePiece;
                if (index == -1)
                {
                    return(-1);            //peer has no more pieces left to offer
                }
            } while (fileSavingController.DownloadedPieces[index]);
            return(index);
        }
Ejemplo n.º 2
0
        private static void Download(List <Peer> peerList, ExtendedTorrent torrent)
        {
            FileSavingController fileSavingController = new FileSavingController(torrent);

            while (true)
            {
                foreach (var peer in peerList)
                {
                    int success = PeerWireProtocolHandler.ConnectToPeer(peer, torrent, torrent.PeerId, fileSavingController);
                    Console.WriteLine(peer.IpAddress + " " + peer.Port);
                    Console.WriteLine("Error:" + GetErrorMessage(success));

                    if (success == 100)
                    {
                        Environment.Exit(0);
                    }
                }
            }
        }
Ejemplo n.º 3
0
        public static int ConnectToPeer(Peer peer, ExtendedTorrent torrent, string peerId, FileSavingController fileSavingController)
        {
            byte[] handshakeMessage = GetPeerHandshakeMessage(torrent, peerId);
            using (var tcpClient = new TcpClient())
            {
                try
                {
                    var result  = tcpClient.BeginConnect(peer.IpAddress, peer.Port, null, null);
                    var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(_peerTolerance));
                    if (!success)
                    {
                        return(-1);
                    }
                    using (var stream = tcpClient.GetStream())
                    {
                        //handshaking process
                        stream.Write(handshakeMessage, 0, handshakeMessage.Length);
                        byte[] response       = new byte[512];
                        int    responseLength = stream.Read(response, 0, response.Length);
                        int    validationErr  = ValidatePeerHandshake(response, responseLength, torrent);
                        if (validationErr != 0)
                        {
                            return(validationErr);
                        }

                        int responseWithoutHandshakeLength =
                            responseLength - 49 - BitTorrentProtocol.ProtocolNameLength;
                        byte[] responseWithoutHandshake = response.SubArray(49 + BitTorrentProtocol.ProtocolNameLength,
                                                                            responseWithoutHandshakeLength);

                        //handle bitfield message
                        int responseId = GetMessageId(responseWithoutHandshake);
                        switch (responseId)
                        {
                        case -1:
                            return(-1);

                        case 5:
                            HandleBitfieldMessage(responseWithoutHandshake, responseWithoutHandshakeLength, peer, stream);
                            break;

                        default:
                            return(4);
                        }
                        //Send interested: <len=0001><id=2>
                        byte[] interested = new byte[5];
                        Array.Copy(BitConverter.GetBytes(1).Reverse().ToArray(), 0, interested, 0, 4);
                        interested[4] = Convert.ToByte(2);
                        stream.Write(interested, 0, 5);

                        //receive unchoke: <len=0001><id=1>
                        byte[] potentialUnchoke = new byte[5];
                        stream.Read(potentialUnchoke, 0, 5);
                        int len = BitConverter.ToInt32(potentialUnchoke.SubArray(0, 4).Reverse().ToArray(), 0);
                        int id  = Convert.ToInt32(potentialUnchoke[4]);
                        if (len != 1 || id != 1)
                        {
                            return(5);
                        }

                        //4.request for piece

                        //set index of next piece to download
                        int index = GetIndexOfNextPieceAvaivable(peer, fileSavingController);
                        if (index == -1)
                        {
                            return(10);
                        }

                        //downloading sequence
                        int consecutiveFails = 0;
                        while (consecutiveFails < 7)
                        {
                            byte[] piece = DownloadPiece(index, torrent, stream, fileSavingController);
                            if (piece == null)
                            {
                                Console.WriteLine(DateTime.Now + "||Piece #" + index + " Failed to download");
                                consecutiveFails++;
                            }
                            else if (BitConverter.ToInt32(piece.SubArray(0, 4), 0) == -1)
                            {
                                return(-2);
                            }
                            else
                            {
                                bool hashesMatch = CheckIfHashesMatch(piece, torrent, index);
                                if (hashesMatch)
                                {
                                    fileSavingController.SavePiece(piece, index);

                                    Console.WriteLine(DateTime.Now + " | Downloaded piece #" + index);
                                    var compl = fileSavingController.DownloadedPieces.Where(c => c).Count();
                                    Console.WriteLine("Downloaded " + compl + "/" +
                                                      fileSavingController.DownloadedPieces.Length + " pieces");

                                    if (compl == fileSavingController.DownloadedPieces.Length)
                                    {
                                        fileSavingController.PiecesToSingleFile();
                                        return(100);
                                    }
                                }
                                else
                                {
                                    return(11);
                                }
                            }

                            index = GetIndexOfNextPieceAvaivable(peer, fileSavingController);
                            if (index == -1)
                            {
                                return(10);
                            }
                        }
                        return(-1);
                    }
                }
                catch (IOException)
                {
                    return(-1);
                }
            }
        }
Ejemplo n.º 4
0
        private static byte[] DownloadPiece(int index, ExtendedTorrent torrent, NetworkStream stream, FileSavingController fileSavingController)
        {
            long sizeOfPiece = torrent.PieceSize;

            if (fileSavingController.DownloadedPieces.Length - 1 == index)//last package special
            {
                long lastPackageLengthDifference = torrent.NumberOfPieces * torrent.PieceSize -
                                                   torrent.TotalSize;
                sizeOfPiece = torrent.PieceSize - lastPackageLengthDifference;
            }

            int sizeOfRequestedBlock = Utilities.blockSize;

            byte[] piece = new byte[sizeOfPiece];

            for (int pieceOffset = 0; pieceOffset < sizeOfPiece; pieceOffset += sizeOfRequestedBlock)
            {
                int requestLength = sizeOfPiece - pieceOffset < sizeOfRequestedBlock
                    ? (int)(sizeOfPiece - pieceOffset)
                    : sizeOfRequestedBlock;//last block size will be smaller than the rest of
                byte[] requestMessage = GetNextRequestMessage(index, pieceOffset, requestLength);
                stream.Write(requestMessage, 0, requestMessage.Length);

                byte[] response = new byte[requestLength + 13];//13 = 4b len + 1b id + 4b index + 4b begin
                try
                {
                    stream.ReadTimeout = _peerTolerance * 1000;
                    int responseLength = stream.Read(response, 0, response.Length);
                    if (responseLength == 0)
                    {
                        Console.WriteLine("Response Length 0");
                        return(null);
                    }
                    int err = ValidatePieceMessage(response, requestLength, index, pieceOffset);
                    if (err != 0)
                    {
                        //Console.WriteLine("Fail code:"+err);
                        return(null);
                    }
                    Array.Copy(response, 13, piece, pieceOffset, requestLength);
                }
                catch (IOException)
                {
                    Console.WriteLine("Connection timed out");
                    return(BitConverter.GetBytes(-1));
                }
            }
            return(piece);
        }