2014-10-17 11 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: Tylko jedno użycie każdego adresu gniazda (protokół/adres sieciowy/port) jest normalnie dozwolone

Nie wiem dlaczego dostajemy Tylko jedno użycie każdego adresu gniazda (adres protokołu/sieć/port) jest normalnie dozwolone 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) 

Odpowiedz

7

błąd w pytaniu WSAEADDRINUSE (10048):

Adres już w użyciu.
Zwykle dozwolone jest tylko jedno użycie każdego gniazda (protokół/adres IP/port). Ten błąd występuje, gdy aplikacja próbuje powiązać gniazdo z adresem IP/portem, który został już użyty dla istniejącego gniazda lub gniazda, które nie zostało prawidłowo zamknięte lub które jest wciąż w trakcie zamykania. W przypadku aplikacji serwerowych, które muszą wiązać wiele gniazd z tym samym numerem portu , należy rozważyć użycie setsockopt (SO_REUSEADDR). Aplikacje Client zwykle nie wymagają wywoływania połączeń na wszystkich - connect automatycznie wybiera nieużywany port . Po wywołaniu powiązania z adresem wieloznacznym (z udziałem ADDR_ANY) błąd WSAEADDRINUSE może zostać opóźniony do czasu zatwierdzenia konkretnego adresu . Może się to zdarzyć w przypadku połączenia z inną funkcją o późniejszej nazwie: connect, listen, WSAConnect lub WSAJoinLeaf.

Co oznacza, że ​​albo mają wiele HttpClient przedmiotów próbują wiązać się do tej samej lokalnej IP/port w tym samym czasie, lub inna aplikacja korzysta z IP/port że HttpClient próbuje również użyć.

Prawdopodobnie najprawdopodobniej często publikujesz zapytania HTTP i może nie w pełni zużywasz odpowiedzi, co uniemożliwiłoby ASP łączenie się i ponowne wykorzystywanie połączeń, a przez to napotkanie wyczerpania portu w czasie.

+0

Dzięki. To ma sens. Mam wiele instancji HttpClient w różnych wątkach, w jaki sposób jedna instancja HttpClient wie, który port/port jest używany przez inną instancję HttpClient w innym wątku? –

+0

Jeszcze raz dziękuję, Remy. Teraz rozumiem, dlaczego dostałem ten błąd. –

+1

Od Henrik Nielsen: Zazwyczaj jest tak, ponieważ zabrakło efemerycznych portów. Spróbuj użyć tej samej instancji HttpClient dla wszystkich żądań –

0

Uderzyłem to samo w moim narzędziu generatora obciążenia, które próbowało wysłać 200 żądań na sekundę do jednego serwera.

Przeniosłem się z nowej instancji HttpClient na żądanie do singletonu i adresowałem.

Jedna uwaga - początkowo uderzę 2 wnioski/s gardło ale ustawienie DefaultConnectionLimit 500 rozwiązał go:

ServicePointManager.DefaultConnectionLimit = 500; 
Powiązane problemy