Почему Socket.BeginAccept() не работает в моем проекте DLL фонового сервиса?
C# .NET 4.5 Visual Studio 2010
Это скорее упражнение на размышление, чем чтение корректуры моего кода.
Я работаю над разработкой слушателя HTTP, который работает как служба в Windows. Я сделал автономный проект Windows Forms, используя приведенный ниже код, и он отлично работает. Каждый раз, когда поступал запрос, мне удавалось отобразить окно сообщения, в котором отображалось тело HTTP-запроса POST.
Проблема в том, что тот же код при копировании в проект DLL фоновой службы не "перехватывает" отправленные ему HTTP-запросы. Это видно из файла журнала, который я использую для отладки (см. Обращения к Log.Write()
в коде ниже).
Я запускаю все это на одном компьютере, поэтому не думаю, что проблема в том, что порт используется или я использую неправильный IP-адрес.
Мне интересно, не работает ли прослушиватель HTTP, потому что это фоновый сервис, или, может быть, потому что это DLL.
IP-адрес ниже изменен на 1.2.3.4 по соображениям безопасности.
class http_listener
{
bool _stop;
main ()
{
_stop = false;
// start ListenForEvents() in new thread
// [code omitted]
}
private void ListenForEvents(object o)
{
Socket _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
System.Net.IPAddress ipAddress = System.Net.IPAddress.Parse("1.2.3.4");
System.Net.EndPoint endPoint = new System.Net.IPEndPoint(ipAddress, 8000);
_socket.Bind(endPoint);
_socket.Listen(1000);
while (!_stop)
{
Log.Write("this IS written to log every 2 seconds");
Thread.Sleep(2000);
_recvBufSize = 1000; // max bytes to recieve
_begAcceptResult = _socket.BeginAccept(null, _recvBufSize, new AsyncCallback(RequestCallback), _socket);
}
_eventListenerThread = null;
}
private void RequestCallback(IAsyncResult begAcceptResult)
{
Log.Write("this is NOT written to log");
Socket socket = (Socket)begAcceptResult.AsyncState;
byte[] buf;
int bytesTransferred;
Socket endSocket = socket.EndAccept(out buf, out bytesTransferred, begAcceptResult);
string stringTransferred = Encoding.ASCII.GetString(buf, 0, bytesTransferred);
Log.Write(stringTransferred);
}
}
1 ответ
Получил это работает. По какой-то причине порт, который я хотел использовать, был заблокирован брандмауэром Windows, когда я запускал свой сервер как службу, но он не блокировал его, когда я запускал сервер как приложение Forms. У службы было исключение, указанное в настройках брандмауэра, но исключение разрешало связь только по одному конкретному порту; не тот, который я хотел использовать.
Вот настройка, которую я изменил, чтобы разрешить связь через мой порт:
Панель управления> Брандмауэр Windows> Дополнительные параметры> Входящие правила> (щелкните правой кнопкой мыши имя службы) > Свойства> вкладка "Протоколы и порты"> Локальный порт> добавлено 8000 к портам, уже перечисленным там