Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient: Only one usage of each socket address (protocol/network address/port) is normally permitted

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)
like image 345
Tony Bao Avatar asked Oct 17 '14 15:10

Tony Bao


3 Answers

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;
like image 70
ZakiMa Avatar answered Oct 16 '22 17:10

ZakiMa


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.

like image 18
Remy Lebeau Avatar answered Oct 16 '22 17:10

Remy Lebeau


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.

like image 2
YashTheRedDevil Avatar answered Oct 16 '22 15:10

YashTheRedDevil