예제 #1
0
 public void AddPeerToMe(Peer toadd)
 {
     if (Peers.ToList().FindAll(rr => rr.Equals(toadd)).Count == 0 && !ThisPeer.Equals(toadd))
     {
         RegisterPeer(toadd);
         Logger.Log($"New peer: {toadd.ToString()}");
     }
 }
예제 #2
0
파일: Program.cs 프로젝트: Denisa8/SOB
        static async Task Main(string[] args)
        {
            CheckArguments(args);

            var filePath = Path.Combine(Environment.CurrentDirectory, "Downloads");

            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            if (torrentsPath.EndsWith(".torrent", StringComparison.OrdinalIgnoreCase))
            {
                try
                {
                    #region pobranie danych z pliku torrent
                    var torrent = await Torrent.LoadAsync(torrentsPath);

                    if (torrent.AnnounceUrls != null)
                    {
                        Settings.torrentFileInfo.TrackerUrl = torrent.AnnounceUrls[0].FirstOrDefault();
                    }
                    TorrentFileInfo.TorrentHash  = torrent.InfoHash.GetHashCode();
                    TorrentFileInfo.PiecesLength = torrent.PieceLength;
                    TorrentFileInfo.PiecesCount  = torrent.Pieces.Count;
                    TorrentFileInfo.PieceHashes  = new byte[TorrentFileInfo.PiecesCount][];
                    //Settings.torrentFileInfo.ReadPieces =  //dołożyłam, aby sprawdzać, który kawałek dostaliśmy
                    Settings.torrentFileInfo.PathSource = PathSource;
                    Settings.torrentFileInfo.PathNew    = PathNew;
                    for (int i = 0; i < torrent.Pieces.Count; i++)
                    {
                        var byteResult = torrent.Pieces.ReadHash(i);
                        TorrentFileInfo.PieceHashes[i] = byteResult;
                    }
                    #endregion
                    #region Utworzenie peera
                    //peer = new Peer();
                    Settings.ReadPieces = new bool[TorrentFileInfo.PiecesCount];
                    EnablePeerConnections(Settings.port);
                    #endregion
                    #region Tracker
                    clientTracker = new TcpClient();
                    clientTracker.Connect(Settings.trackerIp, Settings.trackerPort);
                    Console.WriteLine("Connected to tracker");
                    var stream = clientTracker.GetStream();

                    List <int> pieces = new List <int>();
                    int        pc     = Settings.torrentFileInfo.GetSavedPiecesCount();

                    for (int i = 0; i < pc; i++)
                    {
                        Settings.ReadPieces[i] = true;
                        pieces.Add(i);
                    }

                    FileTorrent file = new FileTorrent(TorrentFileInfo.TorrentHash.ToString(), pieces, TorrentFileInfo.PiecesCount);
                    Files.TryAdd(TorrentFileInfo.TorrentHash.ToString(), file);


                    //for (int i = 0; i < torrent.Pieces.Count; i++) { pieces.Add(i); };
                    //FileTorrent file = new FileTorrent(TorrentFileInfo.TorrentHash.ToString(), pieces, pieces.Count);
                    //Files.TryAdd(TorrentFileInfo.TorrentHash.ToString(), file);


                    //if ((Settings.port == 1300)) // host na 1300 ma caly plik
                    //    for (int i = 0; i < Settings.ReadPieces.Length; i++)
                    //    {// TEMP
                    //        Settings.ReadPieces[i] = true;
                    //    }

                    InitConnectToTracker connSettings = new InitConnectToTracker(Settings.ID, Settings.peerIp, Settings.port, Files.ToDictionary(x => x.Key, x => x.Value), bannedPeers);
                    TransportObject      ob           = new TransportObject(connSettings);
                    ob.SendObject(stream);

                    //uruchamianie listenera
                    timerTracker = new Timer(async(o) => await ListenTracker(), null, Timeout.Infinite, Timeout.Infinite);
                    timerTracker.Change(0, Timeout.Infinite);
                    #endregion

                    #region wysylanie zapytan o kolejne czesci
                    new Thread(new ThreadStart(() =>
                    {
                        while (!Settings.isStopping)
                        {
                            if (Settings.availablePeer)
                            {
                                Thread.Sleep(5000);
                                Console.WriteLine("---- client.port: " + Settings.port);
                                Console.WriteLine("Having " + Settings.ReadPieces.Where(ffs => ffs == true).Count() + " pieces");

                                if (Settings.ReadPieces.Where(x => x == false).Count() == 0) // klient posiada wszystkie czesci
                                {
                                    Thread.Sleep(10000);                                     // narazie nie wiem co z tym zrobic. teraz jak wszystkie czesci sa pobrane to ten watek jest usypiany
                                    continue;
                                }
                                for (int i = 0; i < Settings.ReadPieces.Length;)
                                {
                                    if (Settings.ReadPieces[i] == false)
                                    {
                                        List <Peer> peersThatICanFinallySendRequestTo = new List <Peer>(); // Do tej listy zbierane sa wszystkie peery z danym kawalkiem
                                        foreach (ConnectedPeer connectedPeer in AvailablePeersOnTracker)
                                        {
                                            if (connectedPeer.Files.TryGetValue(TorrentFileInfo.TorrentHash.ToString(), out FileTorrent fileTorrent))
                                            {
                                                if (fileTorrent.Pieces.Contains(i)) // ustalenie czy dany peer ma kawalek
                                                {
                                                    foreach (KeyValuePair <int, Peer> pair in Peers)
                                                    {
                                                        if (((pair.Value.GUID == connectedPeer.ID) && (!bannedPeers.Contains(pair.Value.GUID)) && (!pair.Value.PieceRequestSent.Contains(i))))
                                                        {
                                                            peersThatICanFinallySendRequestTo.Add(pair.Value);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        if (peersThatICanFinallySendRequestTo.Count == 0) // jesli nie ma zadnych dostepnych peerow
                                        {
                                            //Console.WriteLine("No peers with needed piece");
                                            var x = (DateTime.Now - LastSentRequest).TotalMinutes;
                                            if (x > 2)                                        // oraz ostatni request zostal wyslany 2 minuty temu
                                            {
                                                foreach (KeyValuePair <int, Peer> p in Peers) // resetuj status wyslania requestu o czesc u kazdego polaczonego peera
                                                {
                                                    if (p.Value.PieceRequestSent.Contains(i))
                                                    {
                                                        p.Value.PieceRequestSent.Remove(i);
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            Random r  = new Random();
                                            var index = r.Next(peersThatICanFinallySendRequestTo.Count);
                                            Console.WriteLine("Sending request to peer with index: " + index + " for piece: " + i);
                                            peersThatICanFinallySendRequestTo[index].SendMessage(i); // wysylanie zapytania do losowego peera z listy, zeby rozkladac ruch
                                            peersThatICanFinallySendRequestTo[index].PieceRequestSent.Add(i);
                                            LastSentRequest = DateTime.Now;
                                        }
                                        if (Settings.ReadPieces[i] == true)
                                        {
                                            Console.WriteLine("Piece " + i + " aquired. Moving to the next piece.");
                                            i++;
                                        }
                                    }
                                    else
                                    {
                                        i++;
                                    }
                                }
                            }
                        }
                    })).Start();
                    #endregion
                    # region przetwarzanie zapytan wychodzacych
                    new Thread(new ThreadStart(() =>
                    {
                        while (!Settings.isStopping)
                        {
                            if (Settings.availablePeer)
                            {
                                if (Outgoing.Count == 0)
                                {
                                    Thread.Sleep(1000);
                                    continue;
                                }
                                var pendingMessage = Outgoing[0];
                                Console.WriteLine("Sending ID: " + pendingMessage.PieceIndex + " from outgoing.");
                                pendingMessage.Send();
                                Outgoing.Remove(pendingMessage);
                            }
                        }
                    })).Start();
                    #endregion
                    #region przetwarzanie przychodzacych wiadomosci
                    new Thread(new ThreadStart(() =>
                    {
                        while (!Settings.isStopping)
                        {
                            if (Settings.availablePeer)
                            {
                                Console.WriteLine("Incoming.Count = " + Incoming.Count);
                                if (Incoming.Count == 0)
                                {
                                    Thread.Sleep(5000);
                                    continue;
                                }

                                var pendingMessage = Incoming[0];
                                if (bannedPeers.Contains(pendingMessage.Guid))
                                {
                                    Incoming.Remove(pendingMessage);
                                    continue;
                                }
                                if (pendingMessage.Type == 1)
                                {
                                    Console.WriteLine("Got piece with index: " + pendingMessage.PieceIndex);
                                    int id = EndianBitConverter.Big.ToInt32(pendingMessage.EncodedMessage, 0); //tutaj masz, który kawałek Ci przyszedł
                                    if (Settings.ReadPieces[pendingMessage.PieceIndex] == true)                // jesli juz mamy taka czesc to zignorowac wiadomosc
                                    {
                                        Console.WriteLine(pendingMessage.PieceIndex + " --- Got it");
                                        Incoming.Remove(pendingMessage);
                                    }
                                    else
                                    {
                                        //  Console.WriteLine("Saving piece: " + pendingMessage.PieceIndex + " from incoming");
                                        Settings.torrentFileInfo.WriteFilePiece(pendingMessage.PieceIndex, pendingMessage.EncodedMessage);
                                        Settings.ReadPieces[pendingMessage.PieceIndex] = true;

                                        //  Console.WriteLine("Wysylanie na tracker ze otrzymano " + pendingMessage.PieceIndex + "czesc pliku " + torrent.Name);
                                        var receivePieceFile = new ReceivePieceFile(TorrentFileInfo.TorrentHash.ToString(), pendingMessage.PieceIndex);
                                        Tools.Send(clientTracker.GetStream(), new TransportObject((object)receivePieceFile));
                                        Incoming.Remove(pendingMessage);
                                    }
                                }
                                else if (pendingMessage.Type == 0)
                                {
                                    byte[] encodedMessage;
                                    Console.WriteLine("Got request for piece: " + pendingMessage.PieceIndex);
                                    if (Settings.sendCorrectData)
                                    {
                                        encodedMessage = Peer.EncodePiece(Settings.torrentFileInfo.ReadFilePiece(pendingMessage.PieceIndex), 1);// wczytaj piece jako tablice bajtow);
                                    }
                                    else
                                    {
                                        encodedMessage = Peer.EncodeWrongPiece(pendingMessage.PieceIndex, 1);// wczytaj piece jako tablice bajtow);
                                        Console.WriteLine("Wysyłanie błędnej wiadomości");
                                    }
                                    Outgoing.Add(new PendingMessage
                                    {
                                        PieceIndex     = pendingMessage.PieceIndex,
                                        EncodedMessage = encodedMessage,
                                        Stream         = pendingMessage.Stream,
                                        Type           = 1
                                    });

                                    Console.WriteLine("Saving piece: " + pendingMessage.PieceIndex + " to outgoing");

                                    Incoming.Remove(pendingMessage);
                                }
                                else if (pendingMessage.Type == 2)
                                {
                                    Outgoing.Add(new PendingMessage
                                    {
                                        EncodedMessage = Peer.EncodeGUIDResponse(pendingMessage.IndexPeer),
                                        Type           = 3,
                                        Stream         = pendingMessage.Stream,
                                        IndexPeer      = pendingMessage.IndexPeer
                                    });
                                    Incoming.Remove(pendingMessage);
                                }
                                else if (pendingMessage.Type == 3)
                                {
                                    bool success = false;

                                    foreach (KeyValuePair <int, Peer> peer in Peers)
                                    {
                                        if (peer.Key == pendingMessage.IndexPeer)
                                        {
                                            peer.Value.GUID = pendingMessage.Guid;
                                            success         = true;
                                            break;
                                        }
                                    }
                                    if (!success)
                                    {
                                        Console.WriteLine("Couldnt save GUID");
                                    }

                                    Incoming.Remove(pendingMessage);
                                }
                                else
                                {
                                    Console.WriteLine("Odebrano niepoprawna wiadomosc");
                                }
                                Incoming.Remove(pendingMessage);
                            }
                        }
                    })).Start();
                    #endregion
                    #region zarzadzanie peerami
                    new Thread(new ThreadStart(() =>
                    {
                        while (!Settings.isStopping)
                        {
                            Thread.Sleep(5000);
                            var peers = Peers.ToList();
                            foreach (KeyValuePair <int, Peer> peer in peers)
                            {
                                var lastActiveInMinutes = DateTime.Now - peer.Value.LastActive;
                                if (lastActiveInMinutes.TotalMinutes > Settings.peerTimeoutInMinutes) // jezeli peer jest nieaktywny przez zadany czas
                                {
                                    Console.WriteLine("peer " + peer.Value.GUID + " timed out");
                                    if (Peers.TryRemove(peer.Key, out Peer p))
                                    {
                                        peer.Value.Disconnect(); // rozlacz peera
                                        Console.WriteLine("peer " + p.GUID + " disconnected");
                                    }
                                }
                            }
                        }
                    })).Start();
                    #endregion
                    while (true)
                    {
                    }
                    //p1.ConnectToPeer(1301);
                    //while (!peer.IsConnected && !Peers.Any()) { }
                    //for (int i = 0; i < torrent.Pieces.Count; i++)
                    //{
                    //  var byteResult = torrent.Pieces.ReadHash(i);
                    //  torrentFileInfo.PieceHashes[i] = byteResult;
                    //  Piece p = torrentFileInfo.ReadFilePiece(i);

                    //  if (p == null)
                    //    continue;
                    //  peer.SendPiece(p);
                    //  Thread.Sleep(250);
                    //  //torrentFileInfo.WriteFilePiece(i,p.data);
                    //}
                    Console.ReadLine();
                    clientTracker.Close();
                }