quot;completed":
return TorrentEvent.Completed;
default:
return TorrentEvent.None;
}
}
/// <summary>
/// 将 info_hash 参数从 URL 编码转换为标准的字符串。
/// </summary>
private string ConvertInfoHash(GetPeersInfoInput apiInput)
{
var infoHashBytes = HttpUtility.UrlDecodeToBytes(apiInput.Info_Hash);
if (infoHashBytes == null)
{
Error.Add(TrackerServerConsts.FailureKey,new BString("info_hash 参数不能为空."));
return null;
}
if (infoHashBytes.Length != 20)
{
Error.Add(TrackerServerConsts.FailureKey,new BString($"info_hash 参数的长度 {{{infoHashBytes.Length}}} 不符合 BT 协议规范."));
}
return BitConverter.ToString(infoHashBytes);
}
}
上述代码我们构建了一个新的类型 AnnounceInputParameters
,该类型会将部分参数转换为我们便于操作的类型。这里需要注意的是,我们在 TrackerServerConsts
当中定义了所用到了大部分 BDictionary
关键字。
public enum TorrentEvent
{
/// <summary>
/// 未知状态。
/// </summary>
None,
/// <summary>
/// 已开始。
/// </summary>
Started,
/// <summary>
/// 已停止。
/// </summary>
Stopped,
/// <summary>
/// 已完成。
/// </summary>
Completed
}
/// <summary>
/// 常用的字典 KEY。
/// </summary>
public static class TrackerServerConsts
{
public static readonly BString PeerIdKey = new BString("peer id");
public static readonly BString PeersKey = new BString("peers");
public static readonly BString IntervalKey = new BString("interval");
public static readonly BString MinIntervalKey = new BString("min interval");
public static readonly BString TrackerIdKey = new BString("tracker id");
public static readonly BString CompleteKey = new BString("complete");
public static readonly BString IncompleteKey = new BString("incomplete");
public static readonly BString Port = new BString("port");
public static readonly BString Ip = new BString("ip");
public static readonly string FailureKey = "failure reason";
}
5.2 Peer 的定义
每一个 Peer 我们定义一个 Peer
类型进行表示,我们可以通过 BT 客户端传递的请求参数来实时更新每个 Peer
对象的信息。
除此之外,根据 BT 协议的规定,在返回 Peer 列表的时候可以返回紧凑型的结果和正常 B 编码结果的 Peer 信息。所以我们也会在 Peer
对象中,增加两个方法用于将 Peer 信息进行特定的编码处理。
/// <summary>
/// 每个 BT 下载客户端的定义。
/// </summary>
public class Peer
{
/// <summary>
/// 客户端 IP 端点信息。
/// </summary>
public IPEndPoint ClientAddress { get; private set; }
/// <summary>
/// 客户端的随机 Id,由 BT 客户端生成。
/// </summary>
public string PeerId { get; private set; }
/// <summary>
/// 客户端唯一标识。
/// </summary>
public string UniqueId { get; private set; }
/// <summary>
/// 客户端在本次会话过程中下载的数据量。(以 Byte 为单位)
/// </summary>
public long DownLoaded { get; private set; }
/// <summary>
/// 客户端在本次会话过程当中上传的数据量。(以 Byte 为单位)
/// </summary>
public long Uploaded { get; private set; }
/// <summary>
/// 客户端的下载速度。(以 Byte/秒 为单位)
/// </summary>
public long DownloadSpeed { get; private set; }
/// <summary>
/// 客户端的上传速度。(以 Byte/秒 为单位)
/// </summary>
public long UploadSpeed { get; private set; }
/// <summary>
/// 客户端是否完成了当前种子,True 为已经完成,False 为还未完成。
/// </summary>
public bool IsCompleted { get; private set; }
/// <summary>
/// 最后一次请求 Tracker 服务器的时间。
/// </summary>
public DateTime LastRequestTrackerTime { get; private set; }
/// <summary>
/// Peer 还需要下载的