public BEncodedDictionary GetMetaData(InfoHash hash, out bool netError) { netError = false; WireMessage message; ExtHandShack exths; long metadataSize; int piecesNum; byte ut_metadata; try { //连接 if (!client.ConnectAsync(EndPoint.Address, EndPoint.Port).Wait(5000)) { netError = true; Trace.WriteLine("Connect Timeout", "Socket"); return(null); } stream = client.GetStream(); //发送握手 message = new HandShack(hash); SendMessage(message); //接受握手 message = ReceiveMessage <HandShack>(1); if (!message.Legal || !(message as HandShack).SupportExtend) { netError = true; Trace.WriteLine(EndPoint, "HandShack Fail"); return(null); } //发送拓展握手 message = new ExtHandShack() { SupportUtMetadata = true }; SendMessage(message); //接受拓展 exths = ReceiveMessage <ExtHandShack>(); if (!exths.Legal || !exths.CanGetMetadate || exths.MetadataSize > MaxMetadataSize || exths.MetadataSize <= 0) { netError = true; Trace.WriteLine(EndPoint, "ExtendHandShack Fail"); return(null); } metadataSize = exths.MetadataSize; ut_metadata = exths.UtMetadata; piecesNum = (int)Math.Ceiling(metadataSize / (decimal)PieceLength); //开始接受pieces var rtask = ReceivePiecesAsync(metadataSize, piecesNum); //开始发送piece请求 for (int i = 0; i < piecesNum; i++) { message = new ExtQueryPiece(ut_metadata, i); SendMessage(message); } //等待pieces接收完毕 rtask.Wait(); var rawBytes = rtask.Result; if (rawBytes == null) { return(null); } //检查hash值是否正确 using (var sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider()) { byte[] infohash = sha1.ComputeHash(rawBytes); if (!infohash.SequenceEqual(hash.Hash)) { Trace.WriteLine(EndPoint, "Hash Wrong"); return(null); } } return(BEncodedDictionary.DecodeTorrent(rawBytes)); } catch (AggregateException ex) { throw ex.InnerException; } finally { client?.Close(); } }
public async Task <(BEncodedDictionary, bool)> GetMetaDataAsync(InfoHash hash) { try { //连接 Task connectTask = client.ConnectAsync(EndPoint.Address, EndPoint.Port), waitTask = Task.Delay(5000); await Task.WhenAny(waitTask, connectTask); if (!connectTask.IsCompleted || connectTask.Status != TaskStatus.RanToCompletion) { return(null, true); } stream = client.GetStream(); //发送握手 WireMessage message = new HandShack(hash); await SendMessageAsync(message); //接受握手 message = await ReceiveMessageAsync <HandShack>(1); if (!message.Legal || !((HandShack)message).SupportExtend) { return(null, true); } //发送拓展握手 message = new ExtHandShack() { SupportUtMetadata = true }; await SendMessageAsync(message); //接受拓展 var exths = await ReceiveMessageAsync <ExtHandShack>(); if (!exths.Legal || !exths.CanGetMetadate || exths.MetadataSize > MaxMetadataSize || exths.MetadataSize <= 0) { return(null, true); } var metadataSize = exths.MetadataSize; var utMetadata = exths.UtMetadata; var piecesNum = (int)Math.Ceiling(metadataSize / (decimal)PieceLength); var metaTask = ReceivePiecesAsync(metadataSize, piecesNum); //开始发送piece请求 for (int i = 0; i < piecesNum; i++) { message = new ExtQueryPiece(utMetadata, i); await SendMessageAsync(message); } //等待pieces接收完毕 var metadata = await metaTask; if (metadata == null) { return(null, false); } //检查hash值是否正确 using (var sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider()) { byte[] infohash = sha1.ComputeHash(metadata); if (infohash.SequenceEqual(hash.Hash)) { return(BEncodedDictionary.DecodeTorrent(metadata), false); } return(null, false); } } catch (AggregateException ex) { throw ex.InnerException; } finally { client?.Close(); } }