Esempio n. 1
0
        /// <summary>
        /// Send an announce request for this InfoHash.
        /// </summary>
        /// <param name="infoHash"></param>
        /// <returns></returns>
        public Task Announce(InfoHash infoHash)
        {
            lock (PendingAnnounces) {
                PendingAnnounces.Enqueue(infoHash);
                if (!ProcessingAnnounces)
                {
                    ProcessingAnnounces = true;
                    ProcessQueue();
                }
            }

            return(Task.CompletedTask);
        }
Esempio n. 2
0
        async void ProcessQueue()
        {
            // Ensure this doesn't run on the UI thread as the networking calls can do some (partially) blocking operations.
            // Specifically 'NetworkInterface.GetAllNetworkInterfaces' is synchronous and can take hundreds of milliseconds.
            await MainLoop.SwitchToThreadpool();

            await RateLimiterTask;

            using var sendingClient = new UdpClient();
            var nics = NetworkInterface.GetAllNetworkInterfaces();

            while (true)
            {
                InfoHash infoHash = null;
                lock (PendingAnnounces) {
                    if (PendingAnnounces.Count == 0)
                    {
                        // Enforce a minimum delay before the next announce to avoid killing CPU by iterating network interfaces.
                        RateLimiterTask     = Task.Delay(1000);
                        ProcessingAnnounces = false;
                        break;
                    }
                    infoHash = PendingAnnounces.Dequeue();
                }

                string message = string.Format(BaseSearchString, ListenPort, infoHash.ToHex());
                byte[] data    = Encoding.ASCII.GetBytes(message);

                foreach (var nic in nics)
                {
                    try {
                        sendingClient.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, IPAddress.HostToNetworkOrder(nic.GetIPProperties().GetIPv4Properties().Index));
                        await sendingClient.SendAsync(data, data.Length, MulticastAddressV4).ConfigureAwait(false);
                    } catch {
                        // If data can't be sent, just ignore the error
                    }
                }
            }
        }