Почему HttpListener игнорирует внешние запросы?

Мой компьютер находится за маршрутизатором, который перенаправляет на него порт 80 (как порт 80). Моя проблема в том, что HttpListener игнорирует запросы, адресованные внешнему IP-адресу.

Проблема не в роутере; если я создам пустой консольный проект С# и добавлю только следующие строки кода:

System.Net.Sockets.TcpListener s = new System.Net.Sockets.TcpListener(System.Net.IPAddress.Any, 80);
s.Start();
System.Net.Sockets.TcpClient c = s.AcceptTcpClient();

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

http://localhost/testpath/

в моем браузере ИЛИ если я перейду к

http://externalipaddress/testpath/

в моем браузере - любой адрес успешно пытается подключиться к порту 80. Итак, все настроено правильно — этот компьютер может принимать внутренние и внешние соединения через порт 80.

Теперь, если я создам еще один пустой консольный проект C# и добавлю только следующие строки кода:

System.Net.HttpListener s = new System.Net.HttpListener();
s.Prefixes.Add("http://+:80/testpath/");
s.Start();
System.Net.HttpListenerContext c = s.GetContext();

... во-первых, я получу исключение HttpListenerException, в котором говорится, что доступ запрещен из-за проблем, упомянутых в этот вопрос. Затем он будет работать правильно, когда я закрою Visual Studio и снова открою его как администратор. Программа завершится (правильно), когда я перейду к

http://localhost/testpath/

Однако мой запрос просто истекает, если я перехожу к

http://externalipaddress/testpath/

Почему истекает время ожидания внешнего запроса к HttpListener? Результат воспроизводим с числовым IP-адресом или доменным именем для «внешнего IP-адреса», а также со многими перестановками вложенных папок, косых черт и т. д., а также для префиксы "http://*:80/testpath/", "http://externaldomain:80/testpath/" и "http: //externalipaddress:80/testpath/" (без пробелов; добавлено для форматирования stackoverflow).


person Ben    schedule 23.07.2013    source источник
comment
Вы спрашивали своего интернет-провайдера, блокируют ли они входящие соединения через порт 80? Это необычно, но некоторые делают. Также попробуйте разрешить свой внешний IP-адрес, чтобы он указывал на homeusr51363_516.your_isp.com или аналогичный   -  person rath    schedule 23.07.2013
comment
Если бы мой интернет-провайдер заблокировал входящие соединения, как можно было бы объяснить успех первого кода (который подключается к порту 80 через внешний IP-адрес)? Как уже отмечалось, я пытался использовать числовой IP-адрес и разрешимое доменное имя в запросах браузера.   -  person Ben    schedule 23.07.2013


Ответы (1)


Оказывается, брандмауэр Windows молча принимал входящие запросы на порт 80 из-за пределов локального хоста. Когда я отключил брандмауэр, HttpListener обнаружил внешние запросы. Когда я снова включил брандмауэр, HttpListener перестал обнаруживать внешние запросы. Когда я включил отключенное правило для входящих подключений под названием «Извлечение содержимого BranchCache (HTTP-In)», которое позволяет программе SYSTEM (в которой размещена служба, выполняющая прослушивание TCP для HttpListener) прослушивать порт 80, HttpListener снова обнаружил внешние запросы.

Чтобы найти список правил для входящих подключений в Windows 7, выберите «Пуск» -> «Панель управления» -> «Система и безопасность» -> «Брандмауэр Windows» -> «Дополнительные параметры» -> «Правила для входящих подключений».

person Ben    schedule 24.07.2013
comment
Это большая проблема. Я не хочу добавлять исключение брандмауэра для порта, который я использую. ИМХО это плохая практика. Неужели до сих пор нет решения по этому поводу? - person Filimindji; 01.09.2014
comment
По определению брандмауэра для порта, который вы хотите использовать, должно быть исключение брандмауэра. Сложность здесь заключалась в том, что HttpListener использует что-то вне вашей программы для прослушивания порта 80, поэтому простого разрешения исключения брандмауэра для вашей программы недостаточно, чтобы HttpListener мог прослушивать соединения. - person Ben; 02.09.2014
comment
Спасибо, Бен, ты помог мне понять проблему. Мне кажется, что это все еще проблема безопасности, но, поскольку другого решения нет, я последую вашему совету. - person Filimindji; 02.09.2014