/// <summary> /// Announce the tracker server /// </summary> /// <returns>Return the response of announce information</returns> public async void Announce() { try { HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(Uri); try { BEncodedNode node; using (WebResponse webResponse = await httpRequest.GetResponseAsync()) { Stream stream = webResponse.GetResponseStream(); Debug.Assert(stream != null); int count = Setting.TrackerBufferLength; byte[] rcvBuf = new byte[Setting.TrackerBufferLength]; using (MemoryStream ms = new MemoryStream(Setting.TrackerBufferLength)) { int readLength; do { readLength = await stream.ReadAsync(rcvBuf, 0, count); ms.Write(rcvBuf, 0, readLength); } while (readLength != 0); node = BEncodingFactory.Decode(ms.ToArray()); } } DictNode responseNode = node as DictNode; if (responseNode != null) { AnnounceResponse response = Parse(responseNode); if (response != null) { _timer.Interval = response.Interval * 1000; GotAnnounceResponse(this, response); } else { _timer.Interval = Setting.TrackerFailInterval; BitTorrentException exception = new BitTorrentException("Tracker returns fail message."); ReturnMessageFail(this, exception); } } else { _timer.Interval = Setting.TrackerFailInterval; BitTorrentException exception = new BitTorrentException("Tracker returns fail message."); ReturnMessageFail(this, exception); } } catch (WebException e) { _timer.Interval = Setting.TrackerFailInterval; Debug.Assert(ConnectFail != null); ConnectFail(this, e); } finally { _timer.Start(); } } catch (NullReferenceException) { //Nothing to be done. } }
/// <summary> /// Parse the BEncoded message /// </summary> /// <param name="node">Tracker response BEncoded node</param> /// <returns>return the AnnounceResponse class</returns> private AnnounceResponse Parse(DictNode node) { AnnounceResponse result = new AnnounceResponse(); Debug.Assert(node != null); //Get failure reason if (node.ContainsKey("failure reason")) { BytesNode failureReasonNode = node["failure reason"] as BytesNode; Debug.Assert(failureReasonNode != null); result.FailureReason = failureReasonNode.StringText; } else { result.FailureReason = string.Empty; } //Get warning message if (node.ContainsKey("warning message")) { BytesNode warningMessageNode = node["warning message"] as BytesNode; Debug.Assert(warningMessageNode != null); result.WarningMessage = warningMessageNode.StringText; } else { result.WarningMessage = string.Empty; } //Get interval if (node.ContainsKey("interval")) { IntNode intervalNode = node["interval"] as IntNode; Debug.Assert(intervalNode != null); result.Interval = intervalNode.IntValue; } else { result.Interval = Setting.MaxInterval; } //Get min interval if (node.ContainsKey("min interval")) { IntNode minIntervalNode = node["min interval"] as IntNode; Debug.Assert(minIntervalNode != null); result.MinInterval = minIntervalNode.IntValue; } else { result.MinInterval = result.Interval; } //Get tracker id if (node.ContainsKey("tracker id")) { BytesNode trackerIdNode = node["tracker id"] as BytesNode; Debug.Assert(trackerIdNode != null); result.TrackerId = trackerIdNode.StringText; } else { result.TrackerId = string.Empty; } //Get complete if (node.ContainsKey("complete")) { IntNode completeNode = node["complete"] as IntNode; Debug.Assert(completeNode != null); result.Complete = completeNode.IntValue; } else { result.Complete = 0; } //Get incomplete if (node.ContainsKey("incomplete")) { IntNode incompleteNode = node["incomplete"] as IntNode; Debug.Assert(incompleteNode != null); result.Incomplete = incompleteNode.IntValue; } else { result.Incomplete = 0; } //Get peers result.Peers = GetPeers(node); return(result); }