加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 绑定IP地址只是第一次工作

发布时间:2020-12-15 04:07:54 所属栏目:百科 来源:网络整理
导读:我想从服务器上的一个可用的IP地址发出一个Web请求,所以我使用这个类: public class UseIP{ public string IP { get; private set; } public UseIP(string IP) { this.IP = IP; } public HttpWebRequest CreateWebRequest(Uri uri) { ServicePoint serviceP
我想从服务器上的一个可用的IP地址发出一个Web请求,所以我使用这个类:
public class UseIP
{
    public string IP { get; private set; }

    public UseIP(string IP)
    {
        this.IP = IP;
    }

    public HttpWebRequest CreateWebRequest(Uri uri)
    {
        ServicePoint servicePoint = ServicePointManager.FindServicePoint(uri);
        servicePoint.BindIPEndPointDelegate = new BindIPEndPoint(Bind);
        return WebRequest.Create(uri) as HttpWebRequest;
    }

    private IPEndPoint Bind(ServicePoint servicePoint,IPEndPoint remoteEndPoint,int retryCount)
    {
        IPAddress address = IPAddress.Parse(this.IP);
        return new IPEndPoint(address,0);
    }
}

然后:

UseIP useIP = new UseIP("Valid IP address here...");
Uri uri = new Uri("http://ip.nefsc.noaa.gov");
HttpWebRequest request = useIP.CreateWebRequest(uri);
// Then make the request with the specified IP address

但解决方案第一次工作!

解决方法

一个理论:

HttpWebRequest依赖于底层ServicePoint. ServicePoint表示与URL的实际连接.与浏览器保持与请求之间打开的URL的连接并重用该连接(为了消除打开和关闭每个请求的连接的开销),ServicePoint执行与HttpWebRequest相同的功能.

我认为您正在为ServicePoint设置的BindIPEndPointDelegate在每次使用HttpWebRequest时都不会被调用,因为ServicePoint正在重用该连接.如果您可以强制连接关闭,则下一次调用该URL应该导致ServicePoint需要再次调用BindIPEndPointDelegate.

不幸的是,ServicePoint界面并不能让您直接强制连接关闭.

两个解决方案(每个结果略有不同)

1)对于每个请求,设置HttpWebRequest.KeepAlive = false.在我的测试中,这导致绑定委托每个请求一一对应.

2)将ServicePoint ConnectionLeaseTimeout属性设置为零或一些小值.这将有效地定期强制绑定委托被调用(不是每个请求一对一).

从documentation:

You can use this property to ensure that a ServicePoint object’s
active connections do not remain open indefinitely. This property is
intended for scenarios where connections should be dropped and
reestablished periodically,such as load balancing scenarios.

By default,when KeepAlive is true for a request,the MaxIdleTime
property sets the time-out for closing ServicePoint connections due to
inactivity. If the ServicePoint has active connections,MaxIdleTime
has no effect and the connections remain open indefinitely.

When the ConnectionLeaseTimeout property is set to a value other than
-1,and after the specified time elapses,an active ServicePoint connection is closed after servicing a request by setting KeepAlive to
false in that request.

设置此值会影响由ServicePoint对象管理的所有连接.

public class UseIP
{
    public string IP { get; private set; }

    public UseIP(string IP)
    {
        this.IP = IP;
    }

    public HttpWebRequest CreateWebRequest(Uri uri)
    {
        ServicePoint servicePoint = ServicePointManager.FindServicePoint(uri);
        servicePoint.BindIPEndPointDelegate = (servicePoint,remoteEndPoint,retryCount) =>
        {
            IPAddress address = IPAddress.Parse(this.IP);
            return new IPEndPoint(address,0);
        };

        //Will cause bind to be called periodically
        servicePoint.ConnectionLeaseTimeout = 0;

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
        //will cause bind to be called for each request (as long as the consumer of the request doesn't set it back to true!
        req.KeepAlive = false;

        return req;
    }
}

以下(基本)测试结果在每个请求被绑定的绑定委托中:

static void Main(string[] args)
    {
        //Note,I don't have a multihomed machine,so I'm not using the IP in my test implementation.  The bind delegate increments a counter and returns IPAddress.Any.
        UseIP ip = new UseIP("111.111.111.111");

        for (int i = 0; i < 100; ++i)
        {
            HttpWebRequest req = ip.CreateWebRequest(new Uri("http://www.yahoo.com"));
            using (WebResponse response = req.GetResponse())
            {
            }
        }

        Console.WriteLine(string.Format("Req: {0}",UseIP.RequestCount));
        Console.WriteLine(string.Format("Bind: {0}",UseIP.BindCount));
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读