首页 > 解决方案 > HttpClient 连接状态在使用一段时间后保持在 TIME_WAIT 导致 Socket Exception

问题描述

我们正在使用HttpClient访问WebAPI另一台服务器上的托管服务。我们有一个 MVC5 应用程序,它WebAPI使用 IIS 8.5 从窗口服务器 2012 R2获取数据

下面是用于从 webapi 获取数据的代码

//creating static instance of http client
private static HttpClient client = new HttpClient();

//static method to add common header
static ApiCall()
{
   client.DefaultRequestHeaders.Add("Authorization", 
                 string.Format("Value {0}", AppSettings.ApiSecurityKey));
   client.DefaultRequestHeaders.ConnectionClose = true;
}

//finally posting data to the api
//objprop contains the data and other setting
string url = "apiurl";
var postContent = new StringContent(objprop.DataForPost, 
      System.Text.Encoding.UTF8, objprop.ContentType);
response = client.PostAsync(url, postContent).Result;

但是在 PT 测试期间,我收到了多个TIME_WAIT状态请求。因此,我们得到了套接字异常。

使用 HttpClient 的最佳实践是什么?

是否有任何设置可以在使用后释放插座。

类似的问题在这里
1.如何防止 Socket/Port Exhaustion?
2.为什么 HttpClient 让套接字保持打开状态?
但这对我没有帮助。

编辑 1 更多细节

:InnerException- System.Net.Http.HttpRequestException:发送请求时出错。---> System.Net.WebException:无法连接到远程服务器 ---> System.Net.Sockets.SocketException:每个套接字地址(协议/网络地址/端口)通常只允许使用一次 xxx:80在 System.Net.Sockets.Socket.InternalEndConnect(IAsyncResult asyncResult) 在 System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult) 在 System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket&socket, IPAddress&地址、ConnectSocketState 状态、IAsyncResult asyncResult、Exception& 异常) --- 内部异常堆栈跟踪结束 --- 在 System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext&http://xxxcom//api/GetMenu

标签: c#asp.net-mvcwebsocketasp.net-web-api2dotnet-httpclient

解决方案


你的用法HttpClient是正确的;尽管async正如一些人所评论的那样,最好一直使用它,但这不是您错误的原因。

TIME_WAIT是 TCP/IP 连接的强制阶段;一旦建立连接,发起连接关闭的一方将进入此状态一段预先配置的时间。

TCP/IP 有一个有限的端口池用于进出连接。

新连接使用其中的一个子集(也称为动态或临时端口范围)在每一侧分配一个端口。

您的应用在尝试创建新的传出连接时出现错误“正在使用的地址”,但 TCP 已用完动态范围内的本地端口。

根据启动连接关闭的一端,可能是您的客户端或服务器端口耗尽。

Microsoft 的这篇文章详细介绍了如何修改 Windows TCP/IP 设置以实现高连接速率:

  • 变化TIME_WAIT周期从 120 秒到 30 秒
  • 将动态端口数从 16384 增加到 64511

执行这两项操作会将最大连接速率从 136 个连接/秒增加到大约 2150 个。


推荐阅读