我在主机上有几个IP,并且想要从HttpClient
与HttpRequestMessage
建立连接时选择使用哪一个IP。如果没有我自己去插座并自己编写一个简单的http客户端,这可以做到吗?HttpRequestMessage在多IP环境中配置IP
我在找的相当于connect
的socket
的等级,但是对于HttpClient
......或其他选择。
我在主机上有几个IP,并且想要从HttpClient
与HttpRequestMessage
建立连接时选择使用哪一个IP。如果没有我自己去插座并自己编写一个简单的http客户端,这可以做到吗?HttpRequestMessage在多IP环境中配置IP
我在找的相当于connect
的socket
的等级,但是对于HttpClient
......或其他选择。
所以,如果你使用的是Windows计算机上的默认HttpClient
消息处理程序,HttpClient
将使用.net HttpWebRequest
做其工作。这又依靠ServicePointManager
来提供ServicePoint
来管理到URI的连接。对于任何域,您可以挂钩到其ServicePoint
以更改绑定到IPEndPoint的方式。
如果你把你正在试图连接到并找到其ServicePoint
的URI:
var sp = ServicePointManager.FindServicePoint(uri);
那么你可以:
var sp = ServicePointManager.FindServicePoint(new Uri("http://www.google.com"));
sp.BindIPEndPointDelegate = (servicePoint, remoteEndPoint, retryCount) => {
IPAddress adapterIpAddress = //your chosen adapter's IP address
return new IPEndPoint(adapterIpAddress, 0);
};
如果你想获得真正的爵士,你可以折叠这成一个DelegatingHandler,以便HttpClient为您处理所有事情:
public class RebindingHandler : DelegatingHandler
{
private BindIPEndPoint bindHandler;
public RebindingHandler(IEnumerable<IPAddress> adapterAddresses,
HttpMessageHandler innerHandler = null)
: base(innerHandler ?? new WebRequestHandler())
{
var addresses = adapterAddresses.ToList();
if(!addresses.Any())
{
throw new ArgumentException();
}
var idx = 0;
bindHandler = (servicePoint, remoteEndPoint, retryCount) => {
int i = Interlocked.Increment(ref idx);
uint i2 = unchecked((uint)i);
int index = (int)(((long)i2) % addresses.Count);
IPAddress adapterIpAddress = addresses[index];
return new IPEndPoint(adapterIpAddress, 0);
};
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
var sp = ServicePointManager.FindServicePoint(request.RequestUri);
sp.BindIPEndPointDelegate = bindHandler;
var httpResponseMessage = await base.SendAsync(request, cancellationToken);
return httpResponseMessage;
}
}
然后,您可以:
var addresses = new List<IPAddress>(); //this contains your adapter addresses
var client = new HttpClient(new RebindingHandler(addresses));
,当你使用client
,内部处理程序将自动注册相关的ServicePoint使用周围一堆IPEndPoints的旋转的BindIPEndPoint。
我会碰到一个域。我只需要它看到不同的IP地址。有没有办法避免提到一个URI? – CodeAngry
@CodeAngry我写了一个委托处理程序,应该尽你所需。 – spender
@CodeAngry我对代码进行了更改以避免并发问题。 – spender