Не удается прочитать данные из транспортного соединения: существующее соединение было принудительно закрыто удаленным узлом


У меня есть приложение-сервер и иногда, когда клиент пытается подключиться, я получаю следующую ошибку:

примечание: "не удалось получить поток от клиента или не удалось войти в систему" - это текст, который добавлен мной в оператор catch

и строка, на которой он останавливается ( sThread: строка 96):

tcpClient = (TcpClient)client;
clientStream = tcpClient.GetStream();
sr = new StreamReader(clientStream);
sw = new StreamWriter(clientStream);

// line 96:                 
a = sr.ReadLine();

что может быть причиной этой проблемы? Обратите внимание, что это не происходит все время

12 58

12 ответов:

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

На Английском Языке: Подключение к машина (удаленный хост / сервер / ПК, на котором работает Служба) был сделан, но поскольку служба не была доступна on эта машина, машина не знала, что делать с запросом.

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

Edit-added

возможно, что это вызвано брандмауэром, блокирующим порт, но учитывая, что вы говорите, что он прерывистый ("иногда, когда клиент пытается подключиться"), это очень маловероятно. Я не включил Это изначально, потому что я исключил это мысленно, прежде чем ответить.

Я получил эту ошибку при вызове веб-сервиса. Этот вопрос был также связан с безопасностью на транспортном уровне. Я мог бы вызвать веб-сервис через проект веб-сайта, но при повторном использовании того же кода в тестовом проекте я бы получил исключение WebException, содержащее это сообщение. Добавление следующей строки перед вызовом решило проблему:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Edit

System. Net. ServicePointManager. SecurityProtocol - Это свойство выбор версии протокола SSL (Secure Sockets Layer) или транспорта Протокол TLS (Layer Security), используемый для новых подключений, использующих Только схема защищенного протокола передачи гипертекста (HTTPS); существующая соединения не изменяются.

Я считаю SecurityProtocol конфигурация важна во время квитирования TLS при выборе версии протокола.

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

ClientHello - клиент отправляет сообщение ClientHello с указанием самой высокой версии протокола TLS, которую он поддерживает ...

ServerHello - сервер отвечает сообщением ServerHello, содержащим выбранную версию протокола ... Выбранная версия протокола должна быть самой высокой, которую поддерживают как клиент, так и сервер. Например, если клиент поддерживает протокол TLS версии 1.1, а сервер поддерживает версию 1.2, то следует выбрать версию 1.1; версию 1.2 выбирать не следует.

Не уверен, какие из исправлений в этих сообщениях блога помогли, но один из них отсортировал эту проблему для меня ...

http://briancaos.wordpress.com/2012/07/06/unable-to-read-data-from-the-transport-connection-the-connection-was-closed/

и

http://briancaos.wordpress.com/2012/06/15/an-existing-connection-was-forcibly-closed-by-the-remote-host/

мой конкретный сценарий состоял в том, что служба приложений Azure изменила минимальную версию TLS на 1.2

Я не знаю, если это по умолчанию, но менять его обратно на 1.0 все работало.

вы можете получить доступ к настройке внутри "настройки SSL".

звонки на HTTPS-сервисы с одного из наших серверов также бросали "Не удается прочитать данные из транспортного соединения : существующее соединение было принудительно закрыто" исключение. Служба HTTP, однако, работала нормально. Использовал Wireshark, чтобы увидеть, что это был сбой рукопожатия TLS. В итоге оказалось, что набор шифров на сервере необходимо обновить.

по какой-то причине соединение с сервером было потеряно. Возможно, сервер явно закрыл соединение, или ошибка на сервере вызвала его неожиданное закрытие. Или что-то между клиентом и сервером (коммутатор или маршрутизатор) за подключение.

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

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

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

я клонировал виртуальную машину и запустил ее в другой сети с новым IP-адресом, но не изменил привязки в IIS. Fiddler показывал мне "невозможно прочитать данные из транспортного соединения: существующее соединение было принудительно закрыто удаленным хостом", и IE говорил мне "включить TLS 1.0, TLS 1.1 и TLS 1.2 в расширенных настройках". Изменение привязки к новый IP-адрес решил это для меня.

Я получаю эту проблему в прошлом. Я использую PostgreSQL и когда я запускаю свою программу, иногда она подключается, а иногда она выдает такую ошибку.

когда я экспериментирую с моим кодом, я помещаю свой код подключения в самую первую строку ниже публичной формы. Вот пример:

перед:

    public Form1()
        {
        //HERE LIES SOME CODES FOR RESIZING MY CONTROLS DURING RUNTIME
        //CODE
        //CODE AGAIN
        //ANOTHER CODE
        //CODE NA NAMAN
        //CODE PA RIN!





        //Connect to Database to generate auto number
        NpgsqlConnection iConnect = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Password=pass;Database=DB");
        iConnect.Open();
        NpgsqlCommand iQuery = new NpgsqlCommand("Select * from table1", iConnect);
        NpgsqlDataReader iRead = iQuery.ExecuteReader();
        NpgsqlDataAdapter iAdapter = new NpgsqlDataAdapter(iQuery);

        DataSet iDataSet = new DataSet();
        iAdapter.Fill(iDataSet, "ID");

        MessageBox.Show(iDataSet.Tables["ID"].Rows.Count.ToString());
        }

теперь:

    public Form1()
        {
        //Connect to Database to generate auto number
        NpgsqlConnection iConnect = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Password=pass;Database=DB");
        iConnect.Open();
        NpgsqlCommand iQuery = new NpgsqlCommand("Select * from table1", iConnect);
        NpgsqlDataReader iRead = iQuery.ExecuteReader();
        NpgsqlDataAdapter iAdapter = new NpgsqlDataAdapter(iQuery);

        DataSet iDataSet = new DataSet();
        iAdapter.Fill(iDataSet, "ID");

        MessageBox.Show(iDataSet.Tables["ID"].Rows.Count.ToString());





        //HERE LIES SOME CODES FOR RESIZING MY CONTROLS DURING RUNTIME
        //CODE
        //CODE AGAIN
        //ANOTHER CODE
        //CODE NA NAMAN
        //CODE PA RIN!

        }

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

Удачи В Кодировании!

У меня было стороннее приложение (скрипач) работает, чтобы попытаться увидеть запросы отправляются. Закрытие этого приложения исправлено для меня

это решило мою проблему. Я добавил эту строку перед запросом:

System.Net.ServicePointManager.Expect100Continue = false;

казалось, что на пути сервера был прокси, который не поддерживал поведение 100-continue.

System.Net.ServicePointManager.Expect100Continue = false;

эта проблема иногда возникает по причине прокси-сервера, реализованного на веб-сервере. Чтобы обойти прокси-сервер, поставив эту строку перед вызовом службы отправки.

У нас была очень похожая проблема, когда веб-сайт клиента пытался подключиться к нашей службе веб-API и получить то же самое сообщение. Это начало происходить совершенно неожиданно, когда не было никаких изменений кода или обновлений Windows на сервере, где работал IIS.

в нашем случае оказалось, что вызывающий веб-сайт использовал версию .Net, которая поддерживала только TLS 1.0, и по какой-то причине сервер, на котором работал наш IIS, остановился, похоже, остановился прием вызовов TLS 1.0. Чтобы диагностировать это, мы должны были явно включить TLS через реестр на сервере IIS, а затем перезапустить этот сервер. Это ключи reg:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.0\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.0\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.1\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.1\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.2\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.2\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

If that doesn't do it, you could also experiment with adding the entry for SSL 2.0:


    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
    "DisabledByDefault"=dword:00000000
    "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
    "DisabledByDefault"=dword:00000000
    "Enabled"=dword:00000001

мой ответ еще вопрос есть этот сценарий powershell, который мы использовали для добавления записей:

Примечание: включение старых протоколов безопасности не является хорошей идеей, правильным ответом в нашем случае было заставить сайт клиента обновить его код для использования TLS 1.2, но приведенные выше записи реестра могут помочь диагностировать проблему в первую очередь.