2009-08-27 7 views
35

Mam usługę WCF i aplikację internetową. Aplikacja internetowa wywołuje połączenia z tą usługą WCF w sposób ciągły a.k.a. W naszym środowisku produkcyjnym bardzo rzadko pojawia się ten błąd. Ponieważ jest to działanie wewnętrzne, użytkownicy nie byli świadomi, kiedy ten błąd został zgłoszony.WCF: System.Net.SocketException - dozwolone jest tylko jedno użycie każdego adresu gniazda (protokołu/adresu sieciowego/portu)

Nie można połączyć z http://localhost/QAService/Service.svc. Kod błędu TCP 10048: Tylko jedno użycie każdego adresu gniazda (protokół/adres sieciowy/port) to normalnie dozwolone 127.0.0.1:80. ---> System.Net.WebException: Nie można połączyć się ze zdalnym serwerem ---> System.Net.Sockets.SocketException: Tylko jedno użycie każdego adresu gniazda (protokół/adres sieciowy/port) jest normalnie dozwolone 127.0.0.1:80

mam problemy w reprodukcji tego zachowania w naszym środowisku dev/qA. Upewniłem się, że połączenie klienta jest zamknięte w bloku try..catch..finally. Nadal nie rozumiem, co jest przyczyną problemu. Czy ktoś jest tego świadomy?

Uwaga: Szukałem w tym SO question, ale nie wydaje się być odpowiedzi na mój problem, więc to nie jest powtarzane pytania.

+0

Czy to dlatego, że serwis internetowy używa portu 80, który jest używany przez IIS? Z którego portu korzysta twoja usługa w produkcji? Który port jest skonfigurowany w usługach IIS? – shahkalpesh

+0

To samo 80 dla obu aplikacji. Usługa WCF jest skonfigurowana jako katalog wirtualny wewnątrz katalogu głównego, w którym znajduje się witryna. Mówisz, że czasami może wystąpić konflikt między żądaniem strony internetowej a żądaniem usługi ze strony internetowej próbującej użyć tego samego portu? – asyncwait

+0

Napotkałem na podobną sytuację. Planowanie korzystania z funkcji udostępniania sieciowego tcp w usłudze wcf. http://msdn.microsoft.com/en-us/library/ms734772.aspx Proszę dać mi znać, jeśli to działa –

Odpowiedz

59

Przeciążasz stos TCP/IP. Windows (i myślę, że wszystkie stosy gniazd faktycznie) mają ograniczenie liczby gniazd, które można otworzyć w szybkiej sekwencji z powodu zamykania gniazd podczas normalnej pracy. Za każdym razem, gdy gniazdo jest zamknięte, wchodzi w stan TIME_WAIT na określony czas (240 sekund IIRC). Za każdym razem, gdy odpytywasz, gniazdo jest zużywane poza domyślnym zakresem dynamicznym (myślę, że jest to około 5000 portów dynamicznych tuż powyżej 1024), i za każdym razem, gdy ankieta się kończy, to konkretne gniazdo przechodzi w TIME_WAIT. Jeśli odpytywać wystarczająco często, w końcu zużywają wszystkich dostępnych portów, co spowoduje błędne TCP 10048.

Generalnie WCF próbuje uniknąć tego problemu poprzez łączenie połączeń i takie rzeczy. Zwykle dzieje się tak w przypadku usług wewnętrznych, które nie przechodzą przez Internet. Nie jestem pewien, czy którekolwiek z powiązań wsHttp obsługuje buforowanie połączeń, ale powiązanie netTcp powinno. Zakładam, że nazwane potoki nie napotykają tego problemu. Nie mogłem powiedzieć o powiązaniu MSMQ.

Istnieją dwa rozwiązania, których można użyć w celu obejścia tego problemu. Możesz zwiększyć zakres portów dynamicznych lub skrócić okres TIME_WAIT. Ta pierwsza to prawdopodobnie bezpieczniejsza trasa, ale jeśli zużywasz wyjątkowo dużą ilość gniazd (co nie brzmi jak scenariusz dla twojego scenariusza), zmniejszenie TIME_WAIT jest lepszym rozwiązaniem (lub oboma razem).

Zmiana zakresu dynamicznego portu

  1. Otwarty regedit.
  2. Klawisz otwierający HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parameters
  3. Edytuj (lub utwórz jako DWORD) wartość MaxUserPort.
  4. Ustaw wyższą liczbę. (to znaczy.65534)

Zmiana opóźnienia CZAS_OCZEKIWANIA

  1. Otwórz regedit.
  2. Klawisz otwarty HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parameters
  3. Edytuj (lub utwórz jako DWORD) obiekt TcpTimedWaitDelay.
  4. Ustaw niższy numer. Wartość jest w sekundach. (tj. 60 minut na 1 minutę)

Jedno z powyższych rozwiązań powinno rozwiązać problem. Jeśli utrzyma się po zmianie zakresu portów, spodziewam się zwiększenia okresu głosowania, aby zdarzało się to rzadziej ... to da ci więcej czasu na obejście opóźnienia czasowego. Zmieniłbym czas oczekiwania na zwłokę w ostateczności.

+0

Uhm ... ten link http://msdn.microsoft.com/en-us/library/aa560610 (v = bts.20) .aspx inaczej zmienia parametr TCPTimeWaitDelay. Oznacza to TcpTimedWaitDelay. Jak mogę uzyskać potwierdzenie, że tak jest? Więcej informacji od technetu: http://technet.microsoft.com/en-us/library/cc938217.aspx – Jaans

+0

Czy jest to właściwa obudowa TcpTimeWaitDelay? Jeśli tak, poprawię odpowiedź. – jrista

+1

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters \ TcpTimedWaitDelay – granadaCoder

Powiązane problemy