private UdpTrackerMessage Receive(UdpTrackerMessage originalMessage, byte[] receivedMessage)
        {
            _timeout = 0; //we have receive so unactive the timeout
            var data = receivedMessage;
            var rsp = UdpTrackerMessage.DecodeMessage(data, 0, data.Length, MessageType.Response);

            if (originalMessage.TransactionId != rsp.TransactionId)
            {
                FailureMessage = "Invalid transaction Id in response from udp tracker!";
                return null; //to raise event fail outside
            }
            return rsp;
        }
        private async Task SendRequestAsync(UdpTrackerMessage message)
        {
            var encodedMessage = message.Encode();
            var dataWriter1 = new DataWriter(_tracker.OutputStream);
            try
            {
                dataWriter1.WriteBytes(encodedMessage);
                await dataWriter1.StoreAsync();
            }
            finally
            {
                dataWriter1.DetachStream();
            }

            ClientEngine.MainLoop.QueueTimeout(RetryDelay, () =>
            {
                lock (_lock)
                {
                    if (_timeout == 0)
                    {
                        return false;
                    }
                    if (_timeout <= 4)
                    {
                        _timeout++;
                        try
                        {
                            var dataWriter = new DataWriter(_tracker.OutputStream);
                            try
                            {
                                dataWriter.WriteBytes(encodedMessage);
                                dataWriter.StoreAsync().AsTask().Wait();
                            }
                            finally
                            {
                                dataWriter.DetachStream();
                            }
                        }
                        catch (Exception exception1)
                        {
                            var exception = exception1;
                            lock (_lock)
                            {
                                _timeout = 0;
                            }
                            _taskCompletionSource.TrySetException(exception);
                            return false;
                        }
                        return true;
                    }
                    _timeout = 0;
                    _taskCompletionSource.TrySetException(new Exception("Announce timeout."));
                }
                return false;
            });
        }
 private void CompleteScrape(UdpTrackerMessage message, object state)
 {
     var error = message as ErrorMessage;
     if (error != null)
     {
         FailureMessage = error.Error;
         DoScrapeComplete(false, state);
     }
     else
     {
         //response.Scrapes not used for moment
         //ScrapeResponseMessage response = (ScrapeResponseMessage)message;
         DoScrapeComplete(true, state);
     }
 }
 private async Task<byte[]> SendAndReceiveAsync(UdpTrackerMessage message)
 {
     lock (_lock)
         _timeout = 1;
     _taskCompletionSource = new TaskCompletionSource<byte[]>();
     await SendRequestAsync(message);
     return await _taskCompletionSource.Task;
 }
        private void CompleteAnnounce(UdpTrackerMessage message, object state)
        {
            var error = message as ErrorMessage;
            if (error != null)
            {
                FailureMessage = error.Error;
                DoAnnounceComplete(false, state, new List<Peer>());
            }
            else
            {
                var response = (AnnounceResponseMessage) message;
                DoAnnounceComplete(true, state, response.Peers);

                //TODO seeders and leechers is not used in event.
            }
        }