示例#1
0
        public int RequestForNewPiece()
        {
            int piece = 0, offset = 0, length = 0;

            if (!CurrentFile.GetNextMissingPiece(ref piece, ref offset, ref length))
            {
                return(-1);
            }

            if (!DifferenceBitField.GetPiece(piece))
            {
#if DEBUG
                Console.WriteLine("Cutting connection.. Peer does not have the piece");
#endif
                return(-1); //does not have the piece
            }

#if DEBUG
            Console.WriteLine("Requesting for piece: {0}", piece);
#endif

            byte[] pieceRequest = PacketGenerator.Request(piece, offset, length);
            Send(pieceRequest);
            State = PeerState.DOWNLOADING;

            return(piece);
        }
示例#2
0
        public static byte[] Unchoke()
        {
            PacketGenerator rs = new PacketGenerator();

            rs.WriteInt(1);  //Length
            rs.WriteByte(1); //ID
            return(rs.GetByteArray());
        }
示例#3
0
        public static byte[] NotInterested()
        {
            PacketGenerator rs = new PacketGenerator();

            rs.WriteInt(1);  //Length
            rs.WriteByte(3); //ID
            return(rs.GetByteArray());
        }
示例#4
0
        public void Have(byte[] data)
        {
            PacketGenerator gs    = new PacketGenerator(data);
            int             piece = gs.ReadInt();

#if DEBUG
            Console.WriteLine("Successfully uploaded piece {0}", piece);
#endif
        }
示例#5
0
        public static byte[] BitField(byte[] bitfield)
        {
            PacketGenerator rs = new PacketGenerator();

            rs.WriteInt(1 + bitfield.Length); //Length
            rs.WriteByte(5);                  //ID
            rs.WriteByteArray(bitfield);      //Payload: Bitfield
            return(rs.GetByteArray());
        }
示例#6
0
        public static byte[] Have(int piece)
        {
            PacketGenerator rs = new PacketGenerator();

            rs.WriteInt(5);     //Length
            rs.WriteByte(4);    //ID
            rs.WriteInt(piece); //Payload: Piece ID
            return(rs.GetByteArray());
        }
示例#7
0
        public static byte[] Port(short listen_port) //Used for DHT, currently unimplemented
        {
            PacketGenerator rs = new PacketGenerator();

            rs.WriteInt(3);  //Length
            rs.WriteByte(9); //ID
            rs.WriteShort(listen_port);

            return(rs.GetByteArray());
        }
示例#8
0
        public static byte[] Cancel(int pieceid, int piece_begin_offset, int piecelength) //Same parameters as 'Request' message
        {
            PacketGenerator rs = new PacketGenerator();

            rs.WriteInt(13);                 //Length
            rs.WriteByte(8);                 //ID
            rs.WriteInt(pieceid);            //Payload: Piece ID [index]
            rs.WriteInt(piece_begin_offset); //Payload: Byte Offset [begin]
            rs.WriteInt(piecelength);        //Payload: Piece Read Length [length]

            return(rs.GetByteArray());
        }
示例#9
0
        public static byte[] Piece(int pieceid, int piece_begin_offset, byte[] piece_part) //WARNING: USE REQUESTED AMOUNT OF BYTES (MAX 16KB) AT A TIME, SEND IN MULTIPLE REQUESTS
        {
            PacketGenerator rs = new PacketGenerator();

            rs.WriteInt(9 + piece_part.Length); //Length
            rs.WriteByte(7);                    //ID
            rs.WriteInt(pieceid);               //Payload: Piece ID [index]
            rs.WriteInt(piece_begin_offset);    //Payload: Byte Offset [begin]
            rs.WriteByteArray(piece_part);      //Payload: Piece Block [block]

            return(rs.GetByteArray());
        }
示例#10
0
        public static byte[] Request(int pieceid, int piece_begin_offset, int piecelength) //WARNING: USE 16 KILOBYTES (2^14) AT A TIME, DOWNLOAD IN MULTIPLE REQUESTS
        {
            PacketGenerator rs = new PacketGenerator();

            rs.WriteInt(13);                 //Length
            rs.WriteByte(6);                 //ID
            rs.WriteInt(pieceid);            //Payload: Piece ID [index]
            rs.WriteInt(piece_begin_offset); //Payload: Byte Offset [begin]
            rs.WriteInt(piecelength);        //Payload: Piece Read Length [length]

            return(rs.GetByteArray());
        }
示例#11
0
        public static byte[] Handshake(string clientName, byte[] info_hash, string peer_id)
        {
            PacketGenerator rs = new PacketGenerator();

            byte[] reservedBytes = { 0, 0, 0, 0, 0, 0, 0, 0 };

            rs.WriteByte(Convert.ToByte(clientName.Length));
            rs.WriteString(clientName);
            rs.WriteByteArray(reservedBytes);
            rs.WriteByteArray(info_hash);
            rs.WriteString(peer_id);

            return(rs.GetByteArray());
        }
示例#12
0
        public void FetchAndSendPiece(byte[] packet)
        {
            PacketGenerator gs             = new PacketGenerator(packet);
            int             pieceRequested = gs.ReadInt();
            int             pieceOffset    = gs.ReadInt();
            int             length         = gs.ReadInt();

            byte[] fileData = new byte[1];

            if (CurrentFile.ReadPiece(pieceRequested, ref fileData, pieceOffset, length))
            {
#if DEBUG
                Console.WriteLine("Sending piece: {0}", pieceRequested);
#endif
                byte[] send = PacketGenerator.Piece(pieceRequested, pieceOffset, fileData);
                Send(send);
            }
        }
示例#13
0
        public int SavePieceAndRequestForNewOne(byte[] packet)
        {
            PacketGenerator gs          = new PacketGenerator(packet);
            int             piece       = gs.ReadInt();
            int             pieceOffset = gs.ReadInt();

            byte[] data = gs.ReadLeftoverByteArray();

            CurrentFile.WritePiece(piece, pieceOffset, data);

            Console.WriteLine("Received piece: {0} {1:0.000}%", piece, ((float)CurrentFile.GetDownloadedSize() / (float)CurrentFile.GetSize()) * 100.0);

            if (data.Length < 1024 * 16)
            {
                byte[] have = PacketGenerator.Have(piece);
                Send(have);
                // Console.WriteLine("Successfully downloaded piece: {0}", piece);
            }

            return(RequestForNewPiece());
        }
示例#14
0
        public bool Handshake(PacketGenerator gs)
        {
            int nameLength = (int)gs.ReadByte();

            if (gs.GetLength() < 49 + nameLength)
            {
#if DEBUG
                Console.WriteLine("Invalid namelength! Corrupted packet?");
#endif
                return(false);
            }

            string name = gs.ReadString(nameLength);
            gs.SeekIndex(8); //reservedBytes
            byte[] infoHash = gs.ReadByteArray(20);
            string peerID   = gs.ReadString(20);

            bool HanshakeSuccess = infoHash.SequenceEqual(this.Infohash);

            return(HanshakeSuccess);
        }
示例#15
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
            }
        }
示例#16
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);
        }