2012-02-07 5 views
3

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

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

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

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

+1

Какой.NET классы вы используете? 'TcpClient'? 'Socket'? Или вы пишете свою собственную реализацию? И какой протокол вы используете для общения? FTP? – Douglas

+0

Спасибо за помощь Нет, я не использую Socket или TcpClient. im using: System.Net.HttpWebRequest; и System.Net.HttpWebResponse Я также буду использовать FtpWebRequest и FtpWebResponse –

ответ

4

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

метод

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

Ссылки:

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

+0

Я не уверен, просто выбрав одну конечную точку случайным образом такая хорошая идея, может потребоваться некоторые умнее метод. Например, мой компьютер имеет 4 конечных точки IPv4, и только один из них подключается к Интернету. Остальные три являются виртуальными сетями, которые подключаются к виртуальным машинам. – svick

+0

Нет, код был указан как образец. Я предполагаю, что вы только загрузите небольшое количество сегментов одновременно (может быть, 8?), И в этом случае, очевидно, более разумно перебирать доступные адреса, чем выбирать их наугад. – Douglas

+0

И вам нужно выяснить способ фильтрации ваших виртуальных сетевых адаптеров. – Douglas