3

我是大学四年级的学生。我的毕业项目是一个下载管理器,我打算用 C# 编写代码。当检查 MSDN 文档时,该项目看起来很简单。但问题是我的老师希望我将多宿主纳入项目。他希望下载管理器:

  1. 将用户要下载的文件拆分为多个段。
  2. 对于每个段,DM 应该创建一个连接并从服务器请求该段。
  3. 在所有片段完成下载后,DM 应将片段合并为一个文件。
  4. 如果存在多宿主,则每个连接都应通过(或路由)不同的 ISP(如使用多宿主时,计算机通过多个网络适配器连接到多个 ISP),因为此过程应加速文件的下载。

我可以完成前三个步骤,但我找不到第四步的解决方案,所以任何人都可以帮助我或指导我通过正确的方式。

我不是经验丰富的网络和协议程序员,我只选择了 C#,因为它简化了发送和请求文件的过程。

4

1 回答 1

4

我相信您的答案在于ServicePoint.BindIPEndPointDelegate您可以在HttpWebRequest实例中设置的属性。引用 MSDN:

一些负载平衡技术要求客户端使用特定的本地 IP 地址和端口号,而不是IPAddress.Any(或 IPAddress.IPv6Any对于 Internet 协议版本 6)和临时端口。你BindIPEndPointDelegate可以满足这个要求。

基本上,BindIPEndPointDelegate允许您选择用于连接的本地端点。您可以使用 检索所有本地 IP 地址的列表Dns.GetHostAddresses(Dns.GetHostName()),然后在委托中随机选择一个。但是,您需要小心匹配地址族:如果远程端点是 IPv6,您需要选择本地 IPv6 地址。

我在下面包含一些示例代码。

Uri uri = new Uri("http://google.com");

Random random = new Random();
IPAddress[] localAddresses = Dns.GetHostAddresses(Dns.GetHostName());

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.ServicePoint.BindIPEndPointDelegate =
    (servicePoint, remoteEndPoint, retryCount) =>
    {
        var allowedLocalAddresses = 
            localAddresses.Where(localAddress => 
                localAddress.AddressFamily == remoteEndPoint.AddressFamily).ToArray();

        IPAddress selectedLocalAddress = 
            allowedLocalAddresses[random.Next(allowedLocalAddresses.Length)];

        return new IPEndPoint(selectedLocalAddress, 0);
    };

HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

参考:

编辑:我并不是建议您实际上应该为您的项目随机选择本地地址;上面的代码只是我能想到的最简单的演示。如果您正在建立多个并发连接并希望在所有可用适配器之间最大化负载平衡,那么您应该循环访问您的本地地址;这将确保所有适配器都处理大致相等数量的连接。

于 2012-02-07T19:46:31.133 回答