webrequests with Binding different IPs using BindIPEndPointDelegate does not result in multiple ServicePoints for same host in multi-thread

此生再无相见时 提交于 2019-12-24 00:54:34

问题


Category:

Throughput Increment

Scenario:

Multiple HttpWebRequests need to be send through different ethernet adapters to the same host.

Keys to Remember:

  • Requests are going to same host.
  • There is a built in limit on per-host basis as servicepoint.
  • Number of simultaneous requests to a host can be leveraged by setting System.Net.ServicePointManager.DefaultConnectionLimit to 100 (for example), or by setting webRequest.ServicePoint.ConnectionLimit = 50 (say) for a webrequest objects with same uri . Sources:
    • Max number of concurrent HttpWebRequests (Question)
      • https://stackoverflow.com/a/1361781/3690154 (Answer)
      • https://stackoverflow.com/a/1361932/3690154 (Answer)
    • https://blogs.msdn.microsoft.com/adarshk/2005/01/02/understanding-system-net-connection-management-and-servicepointmanager/ (Discussion)

Sample Code:

Complete Gist(Target Framework .Net 2.0) .

Uri url = new Uri("https://d585tldpucybw.cloudfront.net/docs/default-source/fiddler/fiddler4setup.exe?sfvrsn=80");

        ServicePoint sp = ServicePointManager.FindServicePoint(url);

        sp.BindIPEndPointDelegate = delegate (
            ServicePoint servicePoint,
            IPEndPoint remoteEndPoint,
            int retryCount)
        {                
            // If IPs referenced in localpoint does not exists, this delegate retries a 7000+ times in few seconds, blocking other threads. Take care!!!
            Console.WriteLine("Retry count segment " + segmentEndPoint.segNumber + " is " + retryCount + " for eth with ip " + segmentEndPoint.ipEndPoint);
            //Console.WriteLine("ip: " + segmentEndPoint.ipEndPoint);
            if (retryCount < 200)
            {
                return segmentEndPoint.ipEndPoint;
            }
            else
            {
                return null;
            }
        };

        sp.ConnectionLimit = 5;
        sp.ConnectionLeaseTimeout = 0;

        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
        webRequest.Proxy = null; // if not set, HttpWebRequest searches system-wide proxy settins which takers 2-8 seconds!
        webRequest.ConnectionGroupName = segmentEndPoint.segNumber + "hey";

        webRequest.KeepAlive = false;

        Console.WriteLine("ServicePoint: {0}, Thread: {1}", webRequest.ServicePoint.GetHashCode(), segmentEndPoint.segNumber);

        var response = webRequest.GetResponse();
        response.Close();

want to do:

webreq1 ----- to be sent through ------- eth1
webreq2 ----- to be sent through ------- eth2
webreq3 ----- to be sent through ------- eth3

what is happening:

  • If webreq1 --- sents through connection ---- eth1
    • webreq2 -- sents through connection ---- eth1 ( which is bind to eth2 )
    • webreq3 -- sents through connection ---- eth1 ( which is bind to eth3 )
  • webRequest.ServicePoint.GetHashCode() gives same hash for all webrequests.

Problems (Not Solved):

  • Each webrequest is using the same servicepoint ,although explicitly set to use different ethernet connections via BindIPdelegate on ServicePoint for each HttpWebRequest.

Problems (Resolved):

  • Multiple Request to same host from webrequests in different threads. (Resolved via setting servicepoint.ConnectionLimit)(Source mentioned above).

Further Solution (to be implemented, if not solved):

  • Using Raw Socket.
  • This solution may not work if depends on same servicemanager-servicepoint scenario.

Requested Suggestions. Regards. devprashant.

来源:https://stackoverflow.com/questions/36217696/webrequests-with-binding-different-ips-using-bindipendpointdelegate-does-not-res

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!