3

I am a student in my fourth year in university. My graduation project is a download manager which i intend to code with C#. when checked the MSDN documentation the project looked easy. But the problem is that my teacher wants me to incorporate multihoming to the project. He want the download manager to:

  1. split the file the user wants to download to multiple segments.
  2. for each segment the DM should create a connection and request that segment from the server.
  3. after all segments finish downloading the DM should combine the segments into one file.
  4. If multihoming exists each connection should go(or route) thru different ISP (as when multihoming is used, the computer is connected to more than one ISP thru more than one network adapter) as this process should accelerate the download of the file.

I can accomplish the first three steps but I couldn't find a solution to the fourth step so can anyone pleas help me or guide me thru the right way.

I am not an experienced networking and protocol programer I have only choose C# because it simplify the process of sending and requesting files.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Ahmad Moussa
  • 1,296
  • 18
  • 22
  • 1
    Which .NET classes are you using? `TcpClient`? `Socket`? Or are you writing your own implementation? And which protocol do you use to communicate? FTP? – Douglas Feb 07 '12 at 18:25
  • Thanks for helping No im not using Socket nor TcpClient. im using: System.Net.HttpWebRequest; and System.Net.HttpWebResponse I will also use FtpWebRequest and FtpWebResponse – Ahmad Moussa Feb 07 '12 at 18:55

1 Answers1

4

I believe that your answer lies with the ServicePoint.BindIPEndPointDelegate property, which you can set within your HttpWebRequest instance. Quoting MSDN:

Some load balancing techniques require a client to use a specific local IP address and port number, rather than IPAddress.Any (or IPAddress.IPv6Any for Internet Protocol Version 6) and an ephemeral port. Your BindIPEndPointDelegate can satisfy this requirement.

Basically, BindIPEndPointDelegate lets you select the local endpoint to use for your connection. You can retrieve the list of all local IP addresses using Dns.GetHostAddresses(Dns.GetHostName()), and then pick one at random within the delegate. You do, however, need to be careful to match the address family: If the remote endpoint is IPv6, you need to select a local IPv6 address.

I’m including some sample code below.

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();

References:

Edit: I am not suggesting that you should actually pick local addresses at random for your project; the above code was just the simplest demonstration I could think of. If you’re establishing a number of concurrent connections and want to maximize load-balancing across all available adapters, then you should cycle through your local addresses; this would ensure that all adapters are handling an approximately equal number of connections each.

Community
  • 1
  • 1
Douglas
  • 53,759
  • 13
  • 140
  • 188
  • I'm not sure simply selecting one endpoint at random is such a good idea, some smarter method may be required. For example, my computer has 4 IPv4 endpoints and only one of them connects to the Internet. The other three are virtual networks that connect to virtual machines. – svick Feb 07 '12 at 19:56
  • No, the code was given just as a sample. I assume you would only download a small number of segments concurrently (maybe 8?), in which case, it is obviously more reasonable to cycle through your available addresses than pick them at random. – Douglas Feb 07 '12 at 20:11
  • And you’ll need to figure out a way of filtering out your virtual network adapters. – Douglas Feb 07 '12 at 20:13
  • @svick: Sorry, just realized you weren’t the question poster. (I’m still getting used to the established users on SO.) Your point is valid, but I don’t know how to address it offhand. – Douglas Feb 07 '12 at 21:19
  • Mr @Douglas: thank you very much for your effort I am in the process of testing your suggestion and hope that it will work – Ahmad Moussa Feb 08 '12 at 16:01