public void Download(TrackerResponse trackerResponse) { trackerResponse.Peers = trackerResponse.Peers.Except(Peers.ToArray().Where(m => m != null).Select(m => m.ip)).ToArray(); _ = Task.Factory.StartNew(() => { new Tcp().Download(this, trackerResponse); }, TaskCreationOptions.LongRunning); }
public void Download(TorrentModel torrentModel, TrackerResponse trackerResponse) { var localIp = IPAddress.Parse("127.0.0.1"); Track = trackerResponse.IPEndPoint; var data = trackerResponse.Peers.Where(m => !m.Address.Equals(localIp)).Distinct(new IPEndPointCompare()).OrderBy(m => Guid.NewGuid()).ToList(); ////测试,调试 //var data = new List<IPEndPoint> { // new IPEndPoint(IPAddress.Parse("192.168.1.102"), 29512), // //new IPEndPoint(IPAddress.Parse("192.168.1.102"), 18123) //}; if (data.Count == 0) { _logger.LogInformation("没有满足条件的track"); return; } Total = data.Count; int maxRun = Math.Min(10, Total); SemaphoreSlim = new SemaphoreSlim(maxRun, maxRun); _logger.LogWarnning($"track:{Track},ip总数:" + data.Count); var lockObj = new object(); torrentModel.AddStart(); foreach (var item in data) { if (torrentModel.IsFinish) { return; } //_logger.LogInformation($"{item},占用信号量"); SemaphoreSlim.Wait(); var peer = new Peer(lockObj, this); peer.Process(item, torrentModel.Info, torrentModel); torrentModel.Peers.Add(peer); if (peer.IsConnect) { break; } } for (int i = 0; i < maxRun; i++) { SemaphoreSlim.Wait(); } torrentModel.AddFinish(); _logger.LogWarnning($"{Track}:全部尝试完毕"); _ = torrentModel.TrackAsync(); torrentModel.Connecting(); }
public TrackerResponse Announce() { foreach (AnnounceTier announceTier in AnnounceTiers) { TrackerResponse response = announceTier.Announce(); if (response.Success) { return(response); } } return(new TrackerResponse("Torrent Error: No trackers responded")); }
static void Main(string[] args) { TorrentClient client = new TorrentClient { PeerId = "-CS1000-000000000000" }; client.Start(6881); Torrent torrent = client.LoadTorrentFile("ubuntu-17.04-desktop-amd64.iso.torrent"); TrackerResponse response = torrent.Announce(); Console.WriteLine($"Success: {response.Success}"); Console.Read(); }
static void Main(string[] args) { Console.WriteLine("TorrentSharp Example"); TorrentClient client = new TorrentClient(); Console.WriteLine($"PeerId: {client.PeerId}"); client.Start(6881); Torrent torrent = client.LoadTorrentFile("ubuntu-17.04-desktop-amd64.iso.torrent"); TrackerResponse response = torrent.Announce(); Console.WriteLine($"Success: {response.Success}"); Peer peer = new Peer(client, torrent, response.Peers[0]); Console.Read(); }
private void HandleTrack(byte[] buf, int receiveLen, EndPoint remoteEP) { using (var ms = new MemoryStream(buf, 0, receiveLen)) using (var br = new BinaryReader(ms)) { var action = (ActionsType)IPAddress.NetworkToHostOrder(br.ReadInt32()); if (action == ActionsType.Connect) { var transaction_id = IPAddress.NetworkToHostOrder(br.ReadInt32()); var connection_id = IPAddress.NetworkToHostOrder(br.ReadInt64()); _logger.LogInformation($"收到字节长度:{receiveLen},i32:{transaction_id},i64:{connection_id}"); var ids = ConnecttionId_TransactionId.Create(transaction_id, connection_id); if (_dic.ContainsKey(ids)) { var model = _dic[ids]; //_logger.LogInformation(model.Info.Name ?? model.Info.Files.FirstOrDefault()?.Path.FirstOrDefault()); Announcing(model, connection_id, transaction_id, remoteEP); //Scraping(model, connection_id, transaction_id, remoteEP); } var rk = new ReplayItem() { EndPoint = remoteEP, Ids = ids }; if (_connectingLs.ContainsKey(rk)) { //_logger.LogInformation("已获取udp返回的值,从循环数据源删除相关数据"); _connectingLs.Remove(rk); } _connectingLs.Remove(new ReplayItem { Ids = ids, EndPoint = remoteEP }); } else if (action == ActionsType.Announce) { var transaction_id = IPAddress.NetworkToHostOrder(br.ReadInt32()); var interval = IPAddress.NetworkToHostOrder(br.ReadInt32()); var leechers = IPAddress.NetworkToHostOrder(br.ReadInt32()); var seeders = IPAddress.NetworkToHostOrder(br.ReadInt32()); var ls = new List <IPEndPoint>(); while (ms.Position != ms.Length) { var ip = br.ReadBytes(4); var port = br.ReadUInt16(); var ipendpoint = new IPEndPoint(new IPAddress(ip), port); ls.Add(ipendpoint); } _logger.LogInformation("收到响应 transaction_id:" + transaction_id + ",ip-" + ls.Aggregate("", (s, i) => s + i + ";")); var ids = ConnecttionId_TransactionId.Create(transaction_id); if (_dic.ContainsKey(ids)) { var model = _dic[ids]; var tr = new TrackerResponse(remoteEP as IPEndPoint) { Peers = ls.ToArray(), Interval = interval, Complete = seeders, Incomplete = leechers }; model.Download(tr); IsOk = true; _dic.Remove(ids); if (!model.IsFinish) { _ = Task.Delay(TimeSpan.FromSeconds(tr.Interval)) .ContinueWith(t => { _socket.SendTo(ids.ToArray(), remoteEP); _dic.Add(ids, model); _connectingLs.Add(new ReplayItem { Ids = ids, EndPoint = remoteEP }, 0); }); } } } else if (action == ActionsType.Scrape) { var transaction_id = IPAddress.NetworkToHostOrder(br.ReadInt32()); var ids = ConnecttionId_TransactionId.Create(transaction_id); var complete = IPAddress.NetworkToHostOrder(br.ReadInt32()); var downloaded = IPAddress.NetworkToHostOrder(br.ReadInt32()); var incomplete = IPAddress.NetworkToHostOrder(br.ReadInt32()); // todo do something for Scrape } else if (action == ActionsType.Error) { br.ReadInt32(); var i1 = br.BaseStream.Length; var i2 = br.BaseStream.Position; bool ishavestr = i1 != i2; if (ishavestr) { var strbuf = br.ReadBytes((int)(i1 - i2)); var errMsg = Encoding.UTF8.GetString(strbuf); _logger.LogWarnning($"{remoteEP}:udp errmsg:" + errMsg); } } else { _logger.LogInformation("收到某些响应。。。"); } } }
public TrackerResponse MakeWebRequest(Uri uriQuest, string httpProtocol, string headers) { Encoding encoder = Encoding.GetEncoding(0x4e4); Socket = new SocketEx(Proxy, ProxyServer, ProxyPort, ProxyUser, ProxyPassword); Socket.SetTimeout(0x30d40); Socket.PreAuthenticate = false; log.Info($"Connecting to {uriQuest.Host}:{uriQuest.Port}"); for (int i = 0; i < 5; i++) { try { Socket.Connect(uriQuest.Host, uriQuest.Port); log.Info("Connected Successfully"); break; } catch (Exception ex) { log.Warn(ex); log.Warn("Failed connection attempt: " + i); } } if (!Socket.Connected) { log.Error("Unable to connect. Quitting..."); return(null); } log.Info("======== Sending Command to Tracker ========"); string cmd = "GET " + uriQuest.PathAndQuery + " " + httpProtocol + "\r\n" + headers.Replace("{host}", uriQuest.Host) + "\r\n"; Socket.Send(encoder.GetBytes(cmd)); try { byte[] data = new byte[32 * 1024]; using (MemoryStream memStream = new MemoryStream()) { int dataLen = Socket.Receive(data); while (dataLen > 0) { memStream.Write(data, 0, dataLen); dataLen = Socket.Receive(data); } if (memStream.Length == 0) { log.Info("Error : Tracker Response is empty"); return(null); } TrackerResponse trackerResponse = new TrackerResponse(memStream); memStream.Close(); Socket.Close(); if (trackerResponse.doRedirect) { return(MakeWebRequest(new Uri(trackerResponse.RedirectionURL), httpProtocol, headers)); } log.Info("======== Tracker Response ========"); log.Info(trackerResponse.Headers.ToString()); if (trackerResponse.Dico == null) { log.Warn("*** Failed to decode tracker response :"); log.Warn(trackerResponse.Body); } return(trackerResponse); } } catch (Exception ex) { Socket.Close(); log.Error(ex); return(null); } }
public static async Task TrackAsync(this TorrentModel model) { var info_hash = Encoding.UTF8.GetString(WebUtility.UrlEncodeToBytes(model.Info.Sha1Hash, 0, 20)); var peer_id = Encoding.UTF8.GetString(WebUtility.UrlEncodeToBytes(PeerIdBytes, 0, 20)); var port = Port; var uploaded = 0; var downloaded = 0; var left = model.Info.Length; var eventStr = Event.Started.ToString().ToLower(); var compact = 1; var us = model.Announce_list.SelectMany(m => m).ToList(); if (!string.IsNullOrEmpty(model.Announce.Url)) { us.Add(model.Announce); } var httpUrls = us.Where(m => m.Url.StartsWith("http")).ToList(); if (!httpUrls.Any()) { throw new Exception("不存在http或者https的announce"); } _logger.LogInformation("http track数量:" + httpUrls.Count); //udp tracker:https://blog.csdn.net/wenxinfly/article/details/1504785 foreach (var b in httpUrls) { await ProcessRequest(); async Task ProcessRequest() { try { string url = $"{b.Url}?info_hash={info_hash}&peer_id={peer_id}&port={port}&uploased={uploaded}&downloaded={downloaded}&left={left}&event={eventStr}&compact={compact}"; if (b.Url.Contains('?')) { url = $"{b.Url}&info_hash={info_hash}&peer_id={peer_id}&port={port}&uploased={uploaded}&downloaded={downloaded}&left={left}&event={eventStr}&compact={compact}"; } var responseBuf = await _httpClient.GetByteArrayAsync(url); var res = Parser.DecodingDictionary(new MemoryStream(responseBuf)); if (res.Value.Count == 1) { return; } var m = new TrackerResponse(res, b.Url); if (m.Complete == 0) { return; } _logger.LogInformation("请求" + b.Url + "成功:" + m.Peers.Length); model.Download(m); if (model.IsFinish) { return; } else { _ = Task.Delay(TimeSpan.FromSeconds(m.Interval)) .ContinueWith(t => { _ = ProcessRequest(); }); } } catch (Exception e) { _logger.LogInformation("请求" + b.Url + "发生错误:" + e.Message); } } } }