トランスポート接続からデータを読み取れません:既存の接続がリモートホストによって強制的に閉じられました


103

サーバーアプリを使用していて、クライアントが接続しようとすると、次のエラーが発生することがあります。

ここに画像の説明を入力してください

注:「クライアントからストリームを取得できなかったか、ログインに失敗しました」は、catchステートメントで追加されたテキストです

そして、それが停止する行(sThread:line 96)は次のとおりです。

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

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

この問題の原因は何ですか?それはいつも起こらないことに注意してください

回答:


63

このエラーは通常、ターゲットマシンが実行されているが、接続しようとしているサービスが利用できないことを意味します。(停止したか、クラッシュしたか、別の要求でビジー状態です。)

英語では:への接続マシン(サービスがで実行されることをリモートホスト/サーバ/ PC)をしましたが、サービスが利用できなかったためそのマシン、マシンが要求をどのように処理するかを知りませんでした。

マシンへの接続が利用できない場合は、別のエラーが表示されます。私はそれが何であるかを忘れてしまいましたが、それは「サービス到達不能」または「利用不可能」の線に沿っています。

編集-追加

これはファイアウォールがポートをブロックしていることが原因である可能性がありますが、断続的(「クライアントが接続しようとするときがある」)と言った場合、それはほとんどありません。返信する前に精神的にそれを除外したので、私はもともとそれを含めませんでした。


1
問題は、サーバーを起動すると、サーバーに接続している50クライアントのようなクライアントが存在することです。私はクライアントを受け入れるときに一種の待機信号を実装しました.. while(Program.waitToFinishLoginAtClient == true && ajutor <30){Thread.Sleep(300); ajutor ++; } client = this.tcpListener.AcceptTcpClient(); Program.waitToFinishLoginAtClient = true; ...........およびProgram.waitToFinishAtClientが、クライアントを含むスレッドで変更される
Alex

この「待機」が問題になるだろうか?
Alex

1
私はそれをそのままにすべきですか?待てない?
Alex

1
待機が問題だと思います。確かにあなたのコードを十分に知りませんが、それは確かに聞こえます。独自のサービスを「ハードな方法」で構築したのか、それともWCFやRemotingを使用しているのかだけでも気になります...
David

ここでのコードの小さなニットに基づいて、各接続の個別のスレッド内にある場合、「待機」問題を回避できるように思えます。推測が正しい場合に備えて、マルチスレッドを備えたマルチスレッドTCPサービスの例を次に示します。これは、役立つ場合があります。switchonthecode.com
David

180

Webサービスを呼び出すときにこのエラーを受け取りました。この問題は、トランスポートレベルのセキュリティにも関連していました。WebサービスをWebサイトプロジェクトから呼び出すことはできましたが、テストプロジェクトで同じコードを再利用すると、このメッセージを含むWebExceptionが発生しました。呼び出す前に次の行を追加すると、問題が解決しました。

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

編集する

System.Net.ServicePointManager.SecurityProtocol-このプロパティは、Secure Hypertext Transfer Protocol(HTTPS)スキームのみを使用する新しい接続に使用するSecure Sockets Layer(SSL)またはTransport Layer Security(TLS)プロトコルのバージョンを選択します。既存の接続は変更されません。

SecurityProtocolプロトコルバージョンを選択するときのTLSハンドシェイク中の構成は重要だと思います。

TLSハンドシェイク -このプロトコルは、TLSによる実際のアプリケーションデータの交換に両側で必要なすべての情報を交換するために使用されます。

ClientHello-クライアントは、サポートする最高のTLSプロトコルバージョンを指定してClientHelloメッセージを送信します...

ServerHello-サーバーは、選択されたプロトコルバージョンを含むServerHelloメッセージで応答します...選択されたプロトコルバージョンは、クライアントとサーバーの両方がサポートする最高のものでなければなりません。たとえば、クライアントがTLSバージョン1.1をサポートし、サーバーがバージョン1.2をサポートしている場合は、バージョン1.1を選択する必要があります。バージョン1.2は選択しないでください。


8
これは私を救った!ありがとう。デバッガーで、テスト中にhttpsサービスを呼び出そうとしていますが、OPで発生していた問題が発生していました。
ブレアホームズ

6
これがどのように/なぜ機能するかについてもっと知っていますか?私はPostAsync呼び出しに苦労してきましたが、これも私のエラーを修正するようです。うまくいきましたが、理由も知りたいです。
Kevin Matlock 2017

1
@HansVonnこれをありがとう!時間を大幅に節約できました-なぜ機能するかについては、接続時に使用しているTLSのバージョンを制限しているだけです。
confusedandamused

1
これがまた私を驚かせた!ありがとう
セルジオA.

2
ありがとうございました!これは私を狂わせていました。
mknopf

34

私の特定のケースシナリオは、Azureアプリサービスの最小TLSバージョンを1.2に変更することでした。

これがデフォルトかどうかはわかりませんが、1.0に戻すとうまくいきました。

「SSL設定」内の設定にアクセスできます。


7
ああ、神よ、ありがとう。私は非常に長い間これにこだわっており、WebアプリのSSL設定を確認しました。最小値は1.0ではなく1.2に設定されていました。それを1.0に戻してWebアプリを再起動すると、うまくいきました!どうもありがとうございます!
メイソン

1
@hugo-hilárioさん、どうもありがとうございました。いったいどのようにしてこのようなトリッキーな解決策を見つけましたか?:D
hosjay

それは同様:)私にとっては地獄だった@hosjay
ヒューゴHILARIO

3
私の仲間を救った!
Nitesh

Azure Function v2
Pieter Heemeryck

17

これらのブログ投稿のどの修正が役に立ったかはわかりませんが、そのうちの1つがこの問題を分類してくれました...

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

私を助けたトリックは、WebRequestの使用を中止し、代わりにHttpWebRequestを使用することでした。HttpWebRequestを使用すると、3つの重要な設定を試すことができます。

そして

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

  • 手順1:キープアライブを無効にする
  • ステップ2:ProtocolVersionをVersion10に設定する
  • ステップ3:サービスポイントの数を制限する

1
この答えは、私にとってこの同じ問題を解決したものです。IIS7のHttp Response Headersセクションで「Keep Alive」をオフにしました
drzounds

さらに、この動作を行っていたWebサービスのReference.csにもこのコードを追加する必要がありました。保護されたオーバーライドSystem.Net.WebRequest GetWebRequest(Uri uri){System.Net.HttpWebRequest webRequest =(System.Net.HttpWebRequest)base.GetWebRequest(uri); webRequest.KeepAlive = false; webRequestを返します。}
drzounds

11

いずれかのサーバーからHTTPSサービスを呼び出すと、「トランスポート接続からデータを読み取れません:既存の接続が強制的に閉じられました」という例外スローされていました。ただし、HTTPサービスは正常に機能しました。Wiresharkを使用して、TLSハンドシェイクの失敗であることを確認しました。サーバー上の暗号スイートを更新する必要があるということになった。


これは私に起こっていたものです。期限切れの証明書がSSL接続に送信されました。証明書を更新して動作しました。
Guilherme de Jesus Santos

8

「ハンス・ボン」によると返信。

呼び出す前に次の行を追加すると、問題が解決しました。

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

セキュリティプロトコルを追加して正常に動作した後、正常でないすべてのAPI呼び出しの前に追加する必要があります。私は.netフレームワークのバージョンを少なくとも4.6にアップグレードするだけで、期待どおりに機能し、すべてのAPI呼び出しの前に追加する必要はありません。


1
どうもありがとうございました。あなたは私の日を作りました。これの前に、ファイアウォールの非アクティブ化とServicePointManager.ServerCertificateValidationCallbackの追加もテストしたが機能しなかったと述べた場合、それは一部の人にとって役立つかもしれません。
Tekin

5

これは断続的な問題には役立ちませんが、同様の問題を持つ他の人には役立つかもしれません。

VMのクローンを作成し、別のネットワークで新しいIPアドレスを使用して起動しましたが、IISのバインディングは変更していません。Fiddlerに「トランスポート接続からデータを読み取れません:既存の接続がリモートホストによって強制的に閉じられました」と表示され、IEから「TLS 1.0、TLS 1.1、およびTLS 1.2を詳細設定でオンにする」と通知されました。バインディングを新しいIPアドレスに変更することで解決しました。


2

何らかの理由で、サーバーへの接続が失われました。サーバーが明示的に接続を閉じたか、サーバーのバグが原因で予期せず閉じられた可能性があります。または、クライアントとサーバー(スイッチまたはルーター)の間の接続が切断されました。

問題を引き起こしたのはサーバーコードである可能性があり、そうでない可能性があります。サーバーコードにアクセスできる場合は、そこにデバッグを入れて、クライアント接続が閉じられたことを通知できます。これにより、接続が切断される時期と理由がわかります。

クライアントでは、サーバーがいつでも失敗する可能性を考慮に入れて、コードを記述する必要があります。それはまさにその通りです。ネットワーク接続は本質的に信頼できません。


2

これは私の問題を解決しました。リクエストが行われる前にこの行を追加しました:

System.Net.ServicePointManager.Expect100Continue = false;

100継続動作をサポートしていないサーバーの経路にプロキシがあったようです。


1

私は過去にその問題を抱えています。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!

        }

プログラムは何かをする前に接続を最初に読み取る必要があると思います。よくわかりません。間違っている場合は修正してください。しかし、私の研究によると、それはコードの問題ではありません-それは実際にはマシン自体からのものでした。

ハッピーコーディング!


1
System.Net.ServicePointManager.Expect100Continue = false;

この問題は、Webサーバーに実装されているプロキシサーバーが原因で発生することがあります。sendサービスを呼び出す前にこの行を入力して、プロキシサーバーをバイパスします。


0

送信されるリクエストを確認するために、サードパーティアプリケーション(Fiddler)を実行しました。このアプリケーションを閉じると修正されました


0

クライアントのWebサイトがWeb APIサービスに接続しようとして同じメッセージが表示されるという非常に類似した問題がありました。これは、IISが実行されているサーバーでコードの変更やWindowsの更新が行われていないときに、突然完全に発生し始めました。

今回のケースでは、呼び出し元のWebサイトがTLS 1.0のみをサポートするバージョンの.Netを使用しており、何らかの理由でIISが実行されているサーバーが停止したため、TLS 1.0呼び出しの受け入れが停止したようです。IISのサーバーのレジストリを介してTLSを明示的に有効にし、そのサーバーを再起動する必要があることを診断するには。これらは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を使用するようにさせることでしたが、上記のレジストリエントリは、最初から問題の診断に役立ちます。


0

これが私に起こった理由は、DIプロバイダーに再帰的な依存関係があったためです。私の場合、私は:

services.AddScoped(provider => new CfDbContext(builder.Options));
services.AddScoped(provider => provider.GetService<CfDbContext>());

修正は、2番目のスコープサービス登録を削除することでした。

services.AddScoped(provider => new CfDbContext(builder.Options));

0

ドメインにhttps証明書がある場合は、IISのドメイン名にhttpsバインディングがあることを確認してください。IISで->ドメインを選択->バインドをクリックしますサイトバインドウィンドウが開きます。httpsのバインディングを追加します。


0

同様の問題があり、私が使用したアプリや、ファイアウォール/ロードバランサーをバイパスしたかどうかによって、次のエラーが発生していました。

[blah](#136への)へのHTTPSハンドシェイクが失敗しました。System.IO.IOExceptionトランスポート接続からデータを読み取れません:既存の接続がリモートホストによって強制的に閉じられました

そして

ReadResponse()が失敗しました:サーバーはこの要求に対して完全な応答を返しませんでした。サーバーが0バイトを返しました。

問題は、SSLサーバー証明書が見つからず、いくつかのサーバーにインストールされていないことでした。


0

最初にハンドシェイクを確立できるかどうかを確認してください。以前にファイルをアップロードするときにこの問題があり、アップロードを削除して、パラメーターを指定してログインできるかどうかを確認したところ、問題が存在しないルートであることがわかりました。


0

別のオプションは、try-catchブロックを使用して生成されたエラーコードをチェックし、最初にWebExceptionをキャッチすることです。

私の場合、HTTPSのURLでの証明書の問題のため、エラーコードは「SendFailure」でした。HTTPにヒットすると、問題は解決しました。

https://docs.microsoft.com/en-us/dotnet/api/system.net.webexceptionstatus?redirectedfrom=MSDN&view=netframework-4.8


0

私にとっては、IISバインディングでWebサーバーのIPアドレスが使用されるという問題でした。割り当てられていないすべてのIPを使用するように変更し、アプリケーションが機能し始めました。


0

私はadomdを使用してMicrosoft分析サービスにmdxクエリを実行するpython clrでエラーを経験しました

私はハンス・ボンの助けを借りてそれを解決しました、そしてここにPythonバージョンがあります:

clr.AddReference("System.Net")
from System.Net import ServicePointManager, SecurityProtocolType 
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls

0

後でこれを見つける可能性がある人のために、.NETバージョン4.6以降、私もこの問題に遭遇していました。

web.configファイルで次の行を確認してください。

<compilation debug="true" targetFramework="4.5">
...
<httpRuntime targetFramework="4.5" />

サーバーで4.6.x以降のバージョンの.NETを実行している場合は、これらのtargetFramework値を調整して、サーバーのフレームワークのバージョンと一致させてください。コードのバージョンが4.6.x未満の場合は、.NETをアップグレードし、コードが古いバージョンに依存していない限り、新しいバージョンを使用することをお勧めします(その場合、更新を検討する必要があります)。

targetFrameworksを4.7.2に変更すると、問題は解消しました。

<compilation debug="true" targetFramework="4.7.2">
...
<httpRuntime targetFramework="4.7.2" />

新しいフレームワークは、利用可能な最良のプロトコルを使用してこの問題を整理し、安全でないまたは時代遅れのプロトコルをブロックします。接続または呼び出しを試みているリモートサービスでこのエラーが発生している場合は、古いプロトコルをサポートしていない可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.