## 背景 起因是朋友在使用深信服的 Easy Connect 連接到內網之後,使用 `HttpClient` 訪問對應內網的 API 站點均返回 **System.Net.Sockets.SocketException (10060)** 異常。但使用其他語言的原生 HTTP 庫,比如 Golan ...
背景
起因是朋友在使用深信服的 Easy Connect 連接到內網之後,使用 HttpClient
訪問對應內網的 API 站點均返回 System.Net.Sockets.SocketException (10060) 異常。但使用其他語言的原生 HTTP 庫,比如 Golang / Python / Java 都可以正常訪問,因此懷疑是 HttpClient
的問題。
原因
經過搜索得知,這是存在於 .NET 5 及其以上版本的問題,在 .NET 3.1 是不存在這種情況的。底層原因是從 .NET 5 開始,HttpClient
的底層實現使用的是雙棧套接字(Dual-Stack Sockets),在某些情況下,你的網卡獲得了 IPv6 地址,但是 VPN 處於某種原因不能正確地處理 IPv6 請求時就會導致上述情況的發生。在 PR #55012 中,說明瞭這種情況:
Introduces an AppContext switch
System.Net.DisableIPv6
and environment variableDOTNET_SYSTEM_NET_DISABLEIPV6
to emulate the lack of OS-level IPv6 support. This is useful to workaround dual-stack socket issues when the OS reports support of IPv6, but some other underlying infrastructure element (typically VPN) doesn't function well with IPv6 request.For consistency, this switch also impacts NameResolution and Ping, not only Sockets.
解決
根據 PR 提到的信息,我們只需要在程式啟動的時候使用以下代碼禁用 IPv6 棧即可解決。
AppContext.SetSwitch("System.Net.DisableIPv6",true);
相關 Issue / PR:
- https://github.com/dotnet/runtime/issues/47267
- https://github.com/dotnet/runtime/issues/52287
- https://github.com/dotnet/runtime/issues/44686
- https://github.com/dotnet/runtime/commit/067aa165d97372f3e281786801d014fccea8b12c