WCF: System.Net.SocketException - обычно разрешено только одно использование каждого адреса сокета (протокол / сетевой адрес / порт) - PullRequest
41 голосов
/ 27 августа 2009

У меня есть служба WCF и веб-приложение. Веб-приложение непрерывно выполняет вызовы этой службы WCF a.k.a. В нашей производственной среде я получаю эту ошибку очень редко. Поскольку это внутренняя активность, пользователи не знали, когда возникла эта ошибка.

Не удалось подключиться к http://localhost/QAService/Service.svc. Код ошибки TCP 10048: только одно использование каждого адреса сокета (протокол / сетевой адрес / порт) обычно разрешено 127.0.0.1:80. ---> System.Net.WebException: невозможно подключиться к удаленному серверу ---> System.Net.Sockets.SocketException: Только одно использование каждого адреса сокета (протокол / сетевой адрес / порт) обычно разрешено 127.0.0.1:80

У меня проблемы с воспроизведением этого поведения в нашей среде dev / qa. Я убедился, что клиентское соединение закрывается в блоке try..catch..finally. Все еще не понимаю, что является причиной этой проблемы ... кто-нибудь знает об этом?

Примечание : Я смотрел на этот ТАК вопрос , но, похоже, не отвечает на мою проблему, поэтому это не повторяющиеся вопросы.

Ответы [ 2 ]

68 голосов
/ 27 августа 2009

Вы перегружаете стек TCP / IP. Windows (и я думаю, что на самом деле все стеки сокетов) имеют ограничение на количество сокетов, которые можно открывать в быстрой последовательности из-за того, как сокеты закрываются при нормальной работе. Всякий раз, когда сокет закрыт, он входит в состояние TIME_WAIT на определенное время (240 секунд IIRC). Каждый раз, когда вы опрашиваете, сокет расходуется из динамического диапазона по умолчанию (я думаю, что его около 5000 динамических портов чуть выше 1024), и каждый раз, когда заканчивается опрос, этот конкретный сокет переходит в TIME_WAIT. Если вы будете опрашивать достаточно часто, вы в конечном итоге будете использовать все доступные порты, что приведет к ошибке TCP 10048.

Как правило, WCF пытается избежать этой проблемы, объединяя соединения и тому подобное. Обычно это происходит с внутренними службами, которые не работают через Интернет. Я не уверен, что какая-либо из привязок wsHttp поддерживает пул соединений, но привязка netTcp должна. Я бы предположил, что именованные каналы не сталкиваются с этой проблемой. Я не могу сказать о привязке MSMQ.

Есть два решения, которые вы можете использовать, чтобы обойти эту проблему. Вы можете либо увеличить динамический диапазон портов, либо уменьшить период TIME_WAIT. Первый, вероятно, является более безопасным маршрутом, но если вы потребляете слишком много громкости сокетов (что не похоже на случай для вашего сценария), сокращение TIME_WAIT - лучший вариант (или оба вместе).

Изменение диапазона динамического порта

  1. Открыть regedit.
  2. Открытый ключ HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parameters
  3. Измените (или создайте как DWORD) значение MaxUserPort.
  4. Установите большее значение. (т.е. 65534)

Изменение задержки TIME_WAIT

  1. Открыть regedit.
  2. Открытый ключ HKLM \ System \ CurrentControlSet \ Services \ Tcpip \ Parameters
  3. Редактировать (или создать как DWORD) TcpTimedWaitDelay.
  4. Установите меньшее значение. Значение в секундах. (т.е. 60 с задержкой в ​​1 минуту)

Одно из приведенных выше решений должно решить вашу проблему. Если это не изменится после изменения диапазона портов, я попытаюсь увеличить период вашего опроса, чтобы он происходил реже ... что даст вам больше возможностей для обхода задержки ожидания. В крайнем случае я бы изменил задержку ожидания времени.

8 голосов
/ 01 сентября 2016

HttpClient, хотя он реализует IDisposable - общий объект, вы должны максимально уменьшить количество экземпляров. Вы можете избежать необходимости иметь только один экземпляр для всего времени жизни вашего приложения, а не один для каждого запроса.

Я довольно много об этом писал на http://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

...