19

I'm running this application on a server that has assigned 5 IPs. I use HttpWebRequest to fetch some data from a website. But when I make the connection I have be able to specify which one of the 5 IPs to make the connection from. Does HttpWebRequest support this? If it doesn't can I inherit a class from it to change it's behavior? I need so ideas here.

My code right now is something like:

System.Net.WebRequest request = System.Net.WebRequest.Create(link);
((HttpWebRequest)request).Referer = "http://application.com";
using (System.Net.WebResponse response = request.GetResponse())
{
    StreamReader sr = new StreamReader(response.GetResponseStream());
    return sr.ReadToEnd();
}
Tudor Carean
  • 972
  • 2
  • 12
  • 22

2 Answers2

30

According to this, no. You may have to drop down to using Sockets, where I know you can choose the local IP.

EDIT: actually, it seems that it may be possible. HttpWebRequest has a ServicePoint Property, which in turn has BindIPEndPointDelegate, which may be what you're looking for.

Give me a minute, I'm going to whip up an example...

HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://stackoverflow.com");

req.ServicePoint.BindIPEndPointDelegate = delegate(
    ServicePoint servicePoint,
    IPEndPoint remoteEndPoint,
    int retryCount) {

    if (remoteEndPoint.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) {
        return new IPEndPoint(IPAddress.IPv6Any, 0);
    } else {
        return new IPEndPoint(IPAddress.Any, 0);
    }

};

Console.WriteLine(req.GetResponse().ResponseUri);

Basically, the delegate has to return an IPEndPoint. You can pick whatever you want, but if it can't bind to it, it'll call the delegate again, up to int.MAX_VALUE times. That's why I included code to handle IPv6, since IPAddress.Any is IPv4.

If you don't care about IPv6, you can get rid of that. Also, I leave the actual choosing of the IPAddress as an exercise to the reader :)

Community
  • 1
  • 1
Mike Caron
  • 14,351
  • 4
  • 49
  • 77
  • 1
    that guy wanted to spoof the ip. He wanted to use an IP he doesn't own. In my case these IP are listed on my network interface. – Tudor Carean Jul 27 '10 at 16:00
  • The idea is the same. However, it looks like what you need IS possible... I've edited my answer to reflect this, and I'm in the process of creating an example/testing it... – Mike Caron Jul 27 '10 at 16:50
  • Okay, I've added an example. :D – Mike Caron Jul 27 '10 at 17:01
  • +1 interesting. I tried it and it goes round and round in a loop because it cannot be bound. Thought you could pick random IPs - guess not – BritishDeveloper May 12 '11 at 10:10
  • 2
    BritishDeveloper, you can't pick any IP at random. It has to be the IP address of an adapter attached to your computer. If you keep picking an IP address that it cannot bind, then it will keep calling the delegate. The solution is to either use IPAddress.Any (or the IPV6 equivalent), or enumerate the devices to find one you can use. (I recommend the former) – Mike Caron May 13 '11 at 10:39
  • I've posted a similar [question here](http://stackoverflow.com/questions/12046310/using-client-ip-address-in-httpwebrequest), I would really appreciate if you can help me. –  Aug 20 '12 at 22:55
  • +1. I was having sportic issues connecting to my IPv6 server. All good now. Thanks. – Jesse Chisholm Aug 25 '12 at 22:39
  • @opaera You cannot bind to an IP Address that doesn't belong to any network interface on your server. Use `IPAddress.Any` or pick one that you've god. – Mike Caron Sep 11 '12 at 12:41
  • I have a big batch of ip's on my server, this is exactly what i needed to enable changing which one i use on outbound connections. awesome. – Brady Moritz Nov 21 '12 at 20:15
  • I'm using this for making a lot of outbound connections, using a couple of ip's. Does it make sense to try to reuse the same delegate, or just create a new one for every request? Also I'm seeing occasional errors that seem to be resulting from the wrong ip being used... not sure how this can be happening... – Brady Moritz Aug 12 '13 at 17:29
1

Try this:

System.Net.WebRequest request = System.Net.WebRequest.Create(link);
request.ConnectionGroupName = "MyNameForThisGroup"; 
((HttpWebRequest)request).Referer = "http://application.com";
using (System.Net.WebResponse response = request.GetResponse())
{
    StreamReader sr = new StreamReader(response.GetResponseStream());
    return sr.ReadToEnd();
}

Then try setting the ConnectionGroupName to something distinct per source ip you wish to use.

edit: use this in conjunction with the IP binding delegate from the answer above.

Brady Moritz
  • 8,624
  • 8
  • 66
  • 100