2014-10-17 7 views
5
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); 
} 

}HttpClient: un solo utilizzo di ogni indirizzo socket (protocollo/indirizzo di rete/porta) è normalmente consentito

non so perché si ottiene il solo utilizzo di ogni indirizzo socket (indirizzo di protocollo/network/xx.xxx.xxx.xx porto) è normalmente consentita: 80 errore di

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) 

risposta

7

L'errore in questione è WSAEADDRINUSE (10048):

Indirizzo già in uso.
In genere, è consentito un solo utilizzo di ciascun indirizzo socket (protocollo/indirizzo IP/porta). Questo errore si verifica se un'applicazione tenta di associare un socket a un indirizzo IP/porta che è già stato utilizzato per un socket esistente o un socket che non era chiuso correttamente o che è ancora in fase di chiusura. Per le applicazioni del server che devono associare più socket allo stesso numero di porta , prendere in considerazione l'utilizzo di setsockopt (SO_REUSEADDR). Le applicazioni client di solito non necessitano di chiamare bind at all-connect sceglie automaticamente una porta inutilizzata . Quando viene chiamato bind con un indirizzo jolly (che coinvolge ADDR_ANY), un errore WSAEADDRINUSE potrebbe essere ritardato fino a quando non viene eseguito il commit dell'indirizzo specifico . Ciò potrebbe accadere con una chiamata a un'altra funzione successiva, tra cui connettersi, ascoltare, WSAConnect o WSAJoinLeaf.

Il che significa che hai i più HttpClient oggetti che cercano di legarsi allo stesso IP locale/Porta, allo stesso tempo, o un'altra applicazione sta usando un IP/Porta che un HttpClient sta cercando di utilizzare anche.

Più probabilmente, probabilmente stai inviando richieste HTTP troppo spesso e forse non consumano completamente le risposte, il che impedirebbe a ASP di mettere in comune e riutilizzare le connessioni e quindi di incontrare l'esaurimento delle porte nel tempo.

+0

Grazie. Ha senso. Ho più istanze HttpClient in thread diversi, come una istanza HttpClient sa quale ip/port viene utilizzato dall'altra istanza HttpClient in altro thread? –

+0

Grazie ancora, Remy. Ora capisco perché ho ricevuto questo errore. –

+1

Da Henrik Nielsen: È tipico perché si esauriscono le porte effimere. Prova e riutilizza la stessa istanza di HttpClient per tutte le tue richieste –

0

Ho colpito lo stesso nel mio strumento generatore di carico che ha tentato di inviare 200 richieste/sec a un server.

Mi sono spostato dalla nuova istanza HttpClient per richiesta a un singleton e lo ha risolto.

Una nota - inizialmente mi ha colpito 2 richieste/sec collo di bottiglia, ma l'impostazione DefaultConnectionLimit a 500 risolto:

ServicePointManager.DefaultConnectionLimit = 500;