Порт TCP / IP перестает слушать внезапно - PullRequest
0 голосов
/ 14 сентября 2018

Маленький фон

У меня есть служба Windows (написанная на C # .NET), которая прослушивает несколько разных портов, используя TcpListener. некоторые из портов (8090, 8091, 554, 25100, 25101). Каждый слушатель порта выполняет различные задачи, о которых я не буду подробно говорить здесь, в этом вопросе. Служба продолжает работать в течение нескольких недель без каких-либо проблем, а затем внезапно один из портов 8091 перестает получать новые клиентские соединения. Однако другие порты остаются работоспособными и так же, как служба Windows.

Как используется этот порт (8091)

Пользователь может получить доступ к порту службы Windows из браузера, используя защищенный URL-адрес HTTPS. Например, посмотрите на этот URL.

https://XYZServer.net:8091/ABC/?access=123

В службе Windows я открываю этот порт с помощью TCPListner. Пример кода написан ниже.

m_listener = new TcpListener(IPAddress.Any, 8091);
m_listener.Start();

m_listener.BeginAcceptTcpClient(DoAcceptWebTcpClientCallback, m_listener);

И затем, когда приходит новый запрос на подключение клиента. См. Некоторый пример кода.

private void DoAcceptWebTcpClientCallback(IAsyncResult ar)
        {
            try
            {
                var client = m_listener.EndAcceptTcpClient(ar);

                var webConnection = CreateConnection(client, m_waitForDeviceTimeout);
                webConnection.Start();
            }
            catch (Exception ex)
            {
                s_log.Error(ex, "{0}: Exception", m_serverName);
            }

            try
            {
                BeginAccept();
            }
            catch (Exception ex)
            {
                s_log.Error(ex, "{0}: Exception", m_serverName);
            }
        }

Я связываю sslStream с клиентским подключением. Также я аутентифицирую Сервер, используя сертификат без аутентификации клиента. Пример кода ниже

protected override WebConnection CreateConnection(TcpClient client, int waitForFb4Timeout)
        {
            return new HttpsConnection(SERVER_NAME, client, m_serverCertificate, waitForFb4Timeout); // Create an ssl/tls connection using the configured certificate
        }

public HttpsConnection(string serverName, TcpClient client, X509Certificate serverCertificate, int waitForFb4Timeout) : 
            base (serverName, client, GetStream(client, serverCertificate), DeviceConnection.ProtocolEnum.HTTP, waitForFb4Timeout)
        {
        }

        private static Stream GetStream(TcpClient client, X509Certificate serverCertificate)
        {
            // Create the SslStream using the client's network stream.
            var sslStream = new SslStream(client.GetStream(), false);

            // Authenticate the server but don't require the client to authenticate.
            sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true);

            return sslStream;
        }

Служба Windows ретранслирует все сообщения, поступающие на этот порт, в другое место назначения (сервер WebSocker) и возвращает ответ обратно в браузер. Затем пользователь может увидеть страницу на экране. Это работает нормально в течение нескольких недель, и тогда все внезапные пользователи не могут просматривать страницу, и новые запросы клиентских соединений на порт 8091 перестают поступать.

Когда это происходит, исключений не возникает. Это действительно раздражает и трудно понять, что здесь на самом деле не так ..

Еще одна вещь, которую я хотел бы отметить, что в одной и той же службе Windows мы устанавливаем множество исходящих соединений, использующих диапазон эфемерных портов (49000-65535). Я вижу, как все эти существа используются и используются снова и снова. Однако нет никаких доказательств того, что все порты используются одновременно. Я знаю, что есть способы увеличить диапазон портов, но я еще не пробовал, поскольку не уверен, что мы достигли предела.

Я вижу несколько исключений в коде, связанных с аутентификацией на этом порту.

2018-08-11 01:39:43.8952|ERROR|Fb4RelayServerLib.WebConnections.WebServer.DoAcceptWebTcpClientCallback: HTTPS: Exception System.IO.IOException: Authentication failed because the remote party has closed the transport stream.

Люди на разных форумах предлагали использовать

SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12

Принимая во внимание, что я использую только SslProtocols.Tls (см. Код). Я не пробовал выше, так как в моем случае я получаю это исключение редко и для того же IP-адреса клиента, который также работает нормально.

Я действительно застрял и не знаю, как устранить неполадки и продолжить расследование этой проблемы. Любая помощь в этом отношении будет очень полезна. Заранее большое спасибо и извините за длинный вопрос.

Спасибо

1 Ответ

0 голосов
/ 25 сентября 2018

Правильно, после большой борьбы я наконец-то решил проблему.

Я сделал две вещи, главным образом, для решения проблемы.

1- Добавьте поддержку tls1.1 и tls1.2, который мой продукт изначально отсутствовал.(Как я уже писал в своем вопросе)

2 - Замените AuthenticateAsServer на AuthenticateAsserverAsync.

На самом деле по неизвестной причине функция AuthenticateAsServer зависла и не позволяла приложению принимать какие-либо новые клиентские подключения.

Внесенные выше изменения, похоже, пока работают нормально.Держа пальцы скрещенными:)

...