/// <summary>
        /// Generates the AnnounceParameters from PeerEntry
        /// </summary>
        private AnnounceParameters GenerateAnnounceParameters(byte[] infoHash, PeerEntry entry)
        {
            NameValueCollection c = new NameValueCollection();

            // "info_hash", "peer_id", "port", "uploaded(bytes)", "downloaded", "left", "compact"
            // InfoHash here should be just like what's in HttpRequests
            c.Add("info_hash", System.Web.HttpUtility.UrlEncode(infoHash));
            c.Add("peer_id", entry.PeerID);
            c.Add("port", entry.PeerPort.ToString());
            // Fake the mandatory fields, these are solely used to compute the upload/download speed
            c.Add("uploaded", "0");
            c.Add("downloaded", "0");
            c.Add("left", "1000");
            c.Add("compact", "1");
            // Optional but needs to set for monotorrent tracker
            if (entry.PeerState != MonoTorrent.Common.TorrentEvent.None)
            {
                c.Add("event", entry.PeerEventAsRequestKey);
            }
            // NOTE: "ip" is optional and we don't supply it.
            // AnnounceParameters will set entry.PeerIP as its ClientAddress.
            AnnounceParameters par = new AnnounceParameters(c, IPAddress.Parse(entry.PeerIP));

            return(par);
        }
 /// <summary>
 /// Announces Peer to DHT with AnnounceParameters infomation.
 /// </summary>
 /// <returns>True if successful</returns>
 public void AnnouncePeer(byte[] infoHash, AnnounceParameters pars)
 {
     PeerEntry entry = new PeerEntry(pars);
       Logger.WriteLineIf(LogLevel.Verbose, _log_props,
       string.Format("Peer to be announced to DHT:\n{0}", entry.ToString()));
       AnnouncePeer(infoHash, entry);
 }
        /// <summary>
        /// Announces Peer to DHT with AnnounceParameters infomation.
        /// </summary>
        /// <returns>True if successful</returns>
        public void AnnouncePeer(byte[] infoHash, AnnounceParameters pars)
        {
            PeerEntry entry = new PeerEntry(pars);

            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                               string.Format("Peer to be announced to DHT:\n{0}", entry.ToString()));
            AnnouncePeer(infoHash, entry);
        }
 /// <summary>
 /// Annouces Peer to DHT.
 /// </summary>
 public void AnnouncePeer(byte[] infoHash, PeerEntry peer)
 {
     // Firing DHT Put
     byte[] peer_bytes = peer.SerializeTo();
     byte[] dictKey    = ServiceUtil.GetUrlCompatibleBytes(infoHash);
     try {
         _dictSvc.Put(dictKey, peer_bytes);
     } catch (Exception ex) {
         Logger.WriteLineIf(LogLevel.Error, _log_props,
                            string.Format("Unable to announce peer to DHT. We can try next time. \n{0}", ex));
         return;
     }
     Logger.WriteLineIf(LogLevel.Info, _log_props,
                        string.Format("Successfully announced peer to DHT"));
 }
 /// <summary>
 /// Annouces Peer to DHT.
 /// </summary>
 public void AnnouncePeer(byte[] infoHash, PeerEntry peer)
 {
     // Firing DHT Put
       byte[] peer_bytes = peer.SerializeTo();
       byte[] dictKey = ServiceUtil.GetUrlCompatibleBytes(infoHash);
       try {
     _dictSvc.Put(dictKey, peer_bytes);
       } catch (Exception ex) {
     Logger.WriteLineIf(LogLevel.Error, _log_props,
       string.Format("Unable to announce peer to DHT. We can try next time. \n{0}", ex));
     return;
       }
       Logger.WriteLineIf(LogLevel.Info, _log_props,
       string.Format("Successfully announced peer to DHT"));
 }
        /// <summary>
        /// Gets peers from DHT.
        /// </summary>
        /// <param name="infoHash">The infoHash of the torrent, used as the name in Dht</param>
        /// <returns>
        /// A List of PeerEntries which could have duplicated peers with different
        /// states. Empty List if no peers for this infoHash or the network communication
        /// is temporarily down.
        /// </returns>
        public IEnumerable <PeerEntry> GetPeers(byte[] infoHash)
        {
            Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                               string.Format("Getting peers for infoHash: {0}",
                                             ServiceUtil.GetUrlCompatibleString(infoHash)));
            ICollection <PeerEntry> peers = new List <PeerEntry>();
            // Fire DHT Get
            DictionaryServiceData results;

            try {
                byte[] key = ServiceUtil.GetUrlCompatibleBytes(infoHash);
                results = _dictSvc.Get(key);
            } catch (DictionaryServiceException ex) {
                Logger.WriteLineIf(LogLevel.Error, _log_props, string.Format(
                                       "Exception caught when retrieving peers. Returning empty peers collection.\n{0}",
                                       ex));
                // No big deal. We simply wait until the next time to query again.
                // Return empty collection.
                return(peers);
            }

            Logger.WriteLineIf(LogLevel.Info, _log_props,
                               string.Format("{0} peer(s) retrieved from DHT", results.DataEntries.Length));
            int index = 0;

            foreach (var r in results.DataEntries)
            {
                try {
                    PeerEntry entry = (PeerEntry)DictionaryData.CreateDictionaryData(r.Value);
                    Logger.WriteLineIf(LogLevel.Verbose, _log_props,
                                       string.Format("Peer entry #{0} built:\n{1}", index++, entry.ToString()));
                    peers.Add(entry);
                } catch (Exception ex) {
                    Logger.WriteLineIf(LogLevel.Error, _log_props, string.Format(
                                           "Error occurred when deserializing result from DHT. Continue to parse next.\n{0}",
                                           ex));
                    // Ignore this entry and continue to parse others.
                    continue;
                }
            }
            return(peers);
        }
 /// <summary>
 /// Generates the AnnounceParameters from PeerEntry
 /// </summary>
 private AnnounceParameters GenerateAnnounceParameters(byte[] infoHash, PeerEntry entry)
 {
     NameValueCollection c = new NameValueCollection();
       // "info_hash", "peer_id", "port", "uploaded(bytes)", "downloaded", "left", "compact"
       // InfoHash here should be just like what's in HttpRequests
       c.Add("info_hash", System.Web.HttpUtility.UrlEncode(infoHash));
       c.Add("peer_id", entry.PeerID);
       c.Add("port", entry.PeerPort.ToString());
       // Fake the mandatory fields, these are solely used to compute the upload/download speed
       c.Add("uploaded", "0");
       c.Add("downloaded", "0");
       c.Add("left", "1000");
       c.Add("compact", "1");
       // Optional but needs to set for monotorrent tracker
       if (entry.PeerState != MonoTorrent.Common.TorrentEvent.None) {
     c.Add("event", entry.PeerEventAsRequestKey);
       }
       // NOTE: "ip" is optional and we don't supply it.
       // AnnounceParameters will set entry.PeerIP as its ClientAddress.
       AnnounceParameters par = new AnnounceParameters(c, IPAddress.Parse(entry.PeerIP));
       return par;
 }