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 } }