【问题标题】:How to force ipv6 or ipv4 for HttpWebRequest or WebRequest C#如何为 HttpWebRequest 或 WebRequest C# 强制使用 ipv6 或 ipv4
【发布时间】:2016-09-19 23:27:07
【问题描述】:

来自 node.js 我可以这样做告诉 node.js 使用 ipv6 和 ipv4 发出请求

var http = require("http");
var options = {
  hostname: "google.com",
  family: 4, // set to 6 for ipv6
};
var req = http.request(options, function(res) {
  .. handle result here ..
});
req.write("");
req.end();

family 设置为4 强制使用ipv4,将其设置为6 强制使用ipv6。不设置它可以让任何一个工作。

如何在 C# (.NET 3.5) 中做同样的事情

我可以想到一种方法,即自己为 A 或 AAAA 记录发出 DNS 请求,发出直接 IP 请求并设置 host: 标头。有没有更好的办法?

【问题讨论】:

    标签: c# network-programming ipv6 ipv4


    【解决方案1】:

    几年后,一个 .NET 5 的答案:

    假设您使用的是HttpClient,那么您可以在SocketsHttpHandler 上设置ConnectCallback,因此:

    private static readonly HttpClient _http = new HttpClient(new SocketsHttpHandler() {
        ConnectCallback = async (context, cancellationToken) => {
            // Use DNS to look up the IP address(es) of the target host
            IPHostEntry ipHostEntry = await Dns.GetHostEntryAsync(context.DnsEndPoint.Host);
    
            // Filter for IPv4 addresses only
            IPAddress ipAddress = ipHostEntry
                .AddressList
                .FirstOrDefault(i => i.AddressFamily == AddressFamily.InterNetwork);
    
            // Fail the connection if there aren't any IPV4 addresses
            if (ipAddress == null) {
                throw new Exception($"No IP4 address for {context.DnsEndPoint.Host}");
            }
    
            // Open the connection to the target host/port
            TcpClient tcp = new();
            await tcp.ConnectAsync(ipAddress, context.DnsEndPoint.Port, cancellationToken);
    
            // Return the NetworkStream to the caller
            return tcp.GetStream();
        }),
    });
    
    

    (此设置仅适用于 IPv4,仅适用于 IPv6 将 AddressFamily.InterNetwork 更改为 AddressFamily.InterNetworkV6)

    【讨论】:

      【解决方案2】:

      您可以使用ServicePoint.BindIPEndPointDelegate

      var req = HttpWebRequest.Create(url) as HttpWebRequest;
      
      req.ServicePoint.BindIPEndPointDelegate = (servicePoint, remoteEndPoint, retryCount) =>
      {
          if (remoteEndPoint.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
          {
              return new IPEndPoint(IPAddress.IPv6Any, 0);
          }
      
          throw new InvalidOperationException("no IPv6 address");
      };
      

      【讨论】:

        猜你喜欢
        • 2016-01-07
        • 1970-01-01
        • 1970-01-01
        • 2021-02-10
        • 1970-01-01
        • 2023-04-04
        • 2021-11-27
        • 2012-06-14
        • 2014-04-10
        相关资源
        最近更新 更多