问题
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)
- Max number of concurrent HttpWebRequests (Question)
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