Почему 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 к портам, уже перечисленным там

Другие вопросы по тегам