Example #1
0
        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();
            }
        }
Example #2
0
        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();
            }
        }