如何为 HttpWebRequest 或 WebRequest C# 强制使用 ipv6 或 ipv4

gma*_*man 4 c# network-programming ipv4 ipv6

来自 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();
Run Code Online (Sandbox Code Playgroud)

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

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

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

Che*_*hen 5

您可以使用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");
};
Run Code Online (Sandbox Code Playgroud)


Moo*_*als 5

几年后,.NET 5 给出了答案:

假设您使用的是 a HttpClient,那么您可以这样设置ConnectCallbacka SocketsHttpHandler

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();
    }),
});

Run Code Online (Sandbox Code Playgroud)

(这仅针对 IPv4 设置,若要仅针对 IPv6 设置,请将 AddressFamiliy.InterNetwork 更改为 AddressFamily.InterNetworkV6)

  • 谢谢 !这解决了我的问题。使用“localhost”而不是“127.0.0.1”有时会导致 2 秒的延迟。另请参阅此处解决方案的这一部分 /sf/answers/5014934921/ (2认同)