Загрузка файла с использованием нескольких соединений и множественной адресации

Я студент четвертого курса в университете. Мой дипломный проект - менеджер загрузок, который я собираюсь кодировать с помощью C#. при проверке документации MSDN проект выглядел легко. Но проблема в том, что мой учитель хочет, чтобы я включил multihoming в проект. Он хочет, чтобы менеджер загрузок:

  1. разделить файл, который пользователь хочет загрузить, на несколько сегментов.
  2. для каждого сегмента DM должен создать соединение и запросить этот сегмент с сервера.
  3. после завершения загрузки всех сегментов DM должен объединить сегменты в один файл.
  4. Если существует множественная адресация, каждое соединение должно проходить (или маршрутизироваться) через другого интернет-провайдера (например, когда используется множественная адресация, компьютер подключен к нескольким интернет-провайдерам через несколько сетевых адаптеров), поскольку этот процесс должен ускорить загрузку файла.

Я могу выполнить первые три шага, но я не смог найти решение для четвертого шага, поэтому кто-то может попросить меня помочь или направить меня по правильному пути.

Я не опытный программист сетей и протоколов. Я выбрал только C#, потому что это упрощает процесс отправки и запроса файлов.

1 ответ

Решение

Я считаю, что ваш ответ лежит на ServicePoint.BindIPEndPointDelegate свойство, которое вы можете установить в своем HttpWebRequest пример. Цитирование MSDN:

Некоторые методы балансировки нагрузки требуют, чтобы клиент использовал конкретный локальный IP-адрес и номер порта, а не IPAddress.Any (или же IPAddress.IPv6Any для интернет-протокола версии 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();

Рекомендации:

Редактировать: я не предлагаю вам выбирать произвольные локальные адреса для вашего проекта; приведенный выше код был просто самой простой демонстрацией, которую я мог придумать. Если вы устанавливаете несколько одновременных подключений и хотите максимизировать распределение нагрузки по всем доступным адаптерам, то вам следует циклически просматривать локальные адреса; это гарантировало бы, что все адаптеры обрабатывают примерно одинаковое количество соединений каждый.

Другие вопросы по тегам