13
votes
using (var client = new HttpClient())
{
 client.BaseAddress = new Uri(Url);
 client.DefaultRequestHeaders.Accept.Clear();
 client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));

 using (var task = client.PostAsJsonAsync(Url, body))
 {
    if (task.Result.StatusCode != HttpStatusCode.OK)
       throw new Exception(task.Result.ReasonPhrase);
 }

}

Not Sure why we get the Only one usage of each socket address (protocol/network address/port) is normally permitted xx.xxx.xxx.xx:80 error

System.AggregateException: One or more errors occurred. ---> System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: Only one usage of each socket address (protocol/network address/port) is normally permitted xx.xx.xx.xx:80
at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
   at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
   --- End of inner exception stack trace ---
   at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)
   at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
4

4 Answers

16
votes

The error in question is WSAEADDRINUSE (10048):

Address already in use.
Typically, only one usage of each socket address (protocol/IP address/port) is permitted. This error occurs if an application attempts to bind a socket to an IP address/port that has already been used for an existing socket, or a socket that was not closed properly, or one that is still in the process of closing. For server applications that need to bind multiple sockets to the same port number, consider using setsockopt (SO_REUSEADDR). Client applications usually need not call bind at all—connect chooses an unused port automatically. When bind is called with a wildcard address (involving ADDR_ANY), a WSAEADDRINUSE error could be delayed until the specific address is committed. This could happen with a call to another function later, including connect, listen, WSAConnect, or WSAJoinLeaf.

Which means you either have multiple HttpClient objects trying to bind themselves to the same local IP/Port at the same time, or another app is using an IP/Port that an HttpClient is trying to also use.

More likely, you are probably posting HTTP requests too often, and maybe not fully consuming the responses, which would prevent ASP from pooling and reusing connections and thus encountering port exhaustion over time.

2
votes

I hit the same in my load generator tool which tried to send 200 requests/sec to one server.

I moved from new HttpClient instance per request to a singleton and it did address it.

One note - initially I hit 2 requests/sec bottleneck but setting DefaultConnectionLimit to 500 solved it:

ServicePointManager.DefaultConnectionLimit = 500;
2
votes

Recently ran into this problem on an existing client / server web services setup which has been working for years on Windows 2012 R2 environment.

  • The issue would only appear after a long up time.
  • The issue occurred on the outgoing client connection, not the listening socket on server.
  • Using netstat we could see there was more than enough available sockets.
  • Rebooting the client service did not solve the issue.
  • Rebooting the app pool / iis reset would not solve the issue.
  • Rebooting the server would resolve the issue for a period of time.

After exhausting all checks as suggested by posts and MS articles and combined knowledge of socket connections the call was made that this is a lower level code issue and we engaged Microsoft support.

The outcome was that there is a known issue for KB 4338824 https://support.microsoft.com/en-us/help/4338824/windows-81-update-kb4338824

I paraphrase.... "Applications and services may hang in closesocket() calls and cause applications or services to fail binding to network sockets."

The following patch was applied and the issue was resolved. https://support.microsoft.com/en-us/help/4345424/improvements-and-fixes-windows-8-1-and-server-2012-r2

1
votes

Run command prompt as administrator and type following command. netstat -ano | findstr ":80"

  • a: Displays all connections and listening ports.
  • n: Displays addresses and port numbers in numerical form.
  • o: Displays the owning process ID associated with each connection.

In case if you are using a different port number then replace 80 with the appropriate port number.

The result would show a process id using the 80 port number in the last column. Either you can change the port number in your program or you can kill the process using 80 port number.