Пример #1
0
        public bool BeginConnection()
        {
            Client = new TcpClient();
            Client.ReceiveTimeout = 1000;

            var result = Client.BeginConnect(this.IP, this.Port, null, null);

            Console.WriteLine("Connecting to: {0}:{1}", this.IP, this.Port);

            var success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5));

            if (!success || !Client.Connected)
            {
                return(false);
            }

            Stream             = Client.GetStream();
            Stream.ReadTimeout = 6000;

            byte[] handshake = PacketGenerator.Handshake("BitTorrent protocol", Infohash, PeerClientID);
            Stream.Write(handshake, 0, handshake.Length);
            Stream.Flush();

#if DEBUG
            Console.WriteLine("Sent packet!");
#endif
            byte[] realRead = Read();

            if (realRead.Length < 49)
            {
#if DEBUG
                Console.WriteLine("Invalid handshake packet! Exiting!");
#endif
                Stream.Close();
                Client.Close();
                return(false);
            }

#if DEBUG
            Console.WriteLine("Received: {0} bytes", realRead.Length);
#endif
            PacketGenerator gs = new PacketGenerator(realRead);

            if (!Handshake(gs))
            {
#if DEBUG
                Console.WriteLine("Handshake failed!");
#endif
                Stream.Close();
                Client.Close();
                return(false);
            }

            Console.WriteLine("Connected!");

            State = PeerState.CHOKED;
            ChokeTimer.Reset();

            _ReadThread = new Thread(ReadThread);
            _ReadThread.Start();

            TimeManager resentTimer = new TimeManager();
            while (ThreadWorking)
            {
                if (AliveTimer.GetElapsedSeconds() > 20.0 && resentTimer.GetElapsedSeconds() > 10.0)
                {
                    resentTimer.Reset();
                    if (LastPacketSent == null)
                    {
                        Send(PacketGenerator.KeepAlive());
                    }
                    else
                    {
                        Send(LastPacketSent);
                    }
                }

                if (AliveTimer.GetElapsedSeconds() > 60.0)
                {
                    ThreadWorking = false;
                }

                Thread.Sleep(100);
            }

            ThreadWorking = false;
            return(true);
        }
Пример #2
0
        public void ReadThread()
        {
            Stream.ReadTimeout = 40000;// 40s timeout
            try
            {
                while (ThreadWorking)
                {
                    Send(PacketGenerator.Interested());
                    Send(PacketGenerator.Unchoke());

                    if (State == PeerState.CHOKED)
                    {
                        if (ChokeTimer.GetElapsedSeconds() >= 30.0)
                        {
                            ThreadWorking = false;
                            break;
                        }
                    }

                    byte   packetID = 0;
                    byte[] received = ReadPacket(ref packetID);

                    if (packetID <= 9)
                    {
                        AliveTimer.Reset();
                    }

#if DEBUG
                    Console.WriteLine("Received packet: {0}", packetID == 0xF0 ? "Keep-Alive" : Convert.ToString(packetID));
#endif
                    switch (packetID)
                    {
                    case 0xF0:     //KEEP_ALIVE
                        //AliveTimer.Reset();
                        if (State == PeerState.READY)
                        {
                            if (RequestForNewPiece() == -1)
                            {
                                //all pieces downloaded or failed
                                State         = PeerState.SHAKING;
                                ThreadWorking = false;
                            }
                        }
                        //SendPacket(null, 0);
                        break;

                    case 0:     //CHOKE
                        ChokeTimer.Reset();
                        State = PeerState.CHOKED;
                        break;

                    case 1:    //UNCHOKE
                        if (State == PeerState.CHOKED)
                        {
                            // Send(PacketGenerator.Interested());
                            //Console.WriteLine("Sent Interested Packet!");
                            if (RequestForNewPiece() == -1)
                            {
                                //all pieces downloaded or failed
                                State         = PeerState.SHAKING;
                                ThreadWorking = false;
                            }
                            Send(PacketGenerator.Unchoke());
                        }
                        if (State == PeerState.CHOKED)
                        {
                            State = PeerState.READY;
                        }
                        break;

                    case 2:     //INTERESTED
                        State = PeerState.READY;
                        if (RequestForNewPiece() == -1)
                        {
                            //all pieces downloaded or failed
                            State         = PeerState.SHAKING;
                            ThreadWorking = false;
                        }
                        break;

                    case 3:     //NOTINTERESTED
                        ThreadWorking = false;
#if DEBUG
                        Console.WriteLine("Killing thread.. Not interested.");
#endif
                        break;

                    case 4:             //HAVE
                        Have(received); // OK
                        break;

                    case 5:    //BITFIELD
                        BitField(received);
                        break;

                    case 6:     //REQUEST
                        FetchAndSendPiece(received);
                        break;

                    case 7:     //PIECE
                        State = PeerState.READY;
                        if (SavePieceAndRequestForNewOne(received) == -1)
                        {
                            //all pieces downloaded or failed
                            State         = PeerState.SHAKING;
                            ThreadWorking = false;
                        }
                        break;

                    case 8:     //CANCEL
                        //No need
                        break;

                    case 9:     //PORT
                        //Unused
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                ThreadWorking = false;
#if DEBUG
                Console.WriteLine("ThreadException: {0}", e.Message);
#endif
            }
        }
Пример #3
0
        public bool Start()
        {
            BitFile fs = new BitFile(this.TorrentFile.File.FileName, this.TorrentFile.File.Md5Sum, this.TorrentFile.File.FileSize, (long)Math.Ceiling((double)this.TorrentFile.File.FileSize / (double)this.TorrentFile.PieceSize), this.TorrentFile.PieceSize);

loopStart:

            if (fs.AlmostFinished())
            {
                Console.WriteLine("Flushing buffers!");
                while (!fs.Finished())
                {
                    Thread.Sleep(5);
                }
            }

            if (fs.Finished())
            {
                return(true);
            }

            Console.WriteLine("Announcing...");
            if (!this.TrackerManager.Announce())
            {
                return(false);
            }

            Timer.Reset();

            for (int i = 0; i < TrackerManager.GetPeers().Count; i++)
            {
                var  peerInfo = TrackerManager.GetPeers()[i];
                Peer pr       = new Peer(peerInfo.IP, peerInfo.Port, this.TorrentFile.GetInfoHash(), TrackerManager.GetPeerID(), fs);
                try
                {
                    if (!pr.BeginConnection())
                    {
                        continue;
                    }
                }
                catch (Exception e)
                {
#if DEBUG
                    Console.WriteLine("Exception: {0}", e.Message);
#endif
                    if (pr._ReadThread != null)
                    {
                        pr._ReadThread.Abort();
                    }
                    continue;
                }

                if (fs.AlmostFinished())
                {
                    Console.WriteLine("File successfully downloaded!");
                    goto loopStart;
                }

                if (Timer.GetElapsedSeconds() >= 60.0 * 5)
                {
                    goto loopStart;
                }
            }

            goto loopStart;
        }