예제 #1
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
            }
        }