私は、メッセージとともにSocketExceptionをスローする商用アプリケーションを使用しています。
既存の接続がリモートホストによって強制的に閉じられました
これは、クライアントとサーバー間のソケット接続で発生します。接続は正常に機能しており、大量のデータが転送されていますが、どこからともなく切断されます。
誰もこれを見たことがありますか?原因は何でしょうか?いくつかの原因を推測できますが、このコードにさらに追加して原因を特定する方法はありますか?
コメント/アイデアは大歓迎です。
... 最新の ...
いくつかの.NETトレースからのログがありますが、
System.Net.Sockets Verbose: 0 : [8188] Socket#30180123::Send() DateTime=2010-04-07T20:49:48.6317500Z
System.Net.Sockets Error: 0 : [8188] Exception in the Socket#30180123::Send - An existing connection was forcibly closed by the remote Host DateTime=2010-04-07T20:49:48.6317500Z
System.Net.Sockets Verbose: 0 : [8188] Exiting Socket#30180123::Send() -> 0#0
ロギングの他の部分に基づいて、「0#0」は長さが0バイトのパケットが送信されていることを意味するという事実を見ました。しかし、それは本当に何を意味するのでしょうか?
2つの可能性のうちの1つが発生しています。
1)接続は閉じられますが、データはソケットに書き込まれるため、上記の例外が発生します。 0#0は、ソケットが既に閉じられているため、何も送信されなかったことを意味します。
2)接続はまだ開いており、ゼロバイトのパケットが送信されています(つまり、コードにバグがあります)。0#0は、ゼロバイトのパケットが送信されようとしていることを意味します。
何を考えていますか?それは私が推測する決定的なものではないかもしれませんが、おそらく他の誰かがこのようなことを見ましたか?
これは通常、リモート側が接続を閉じたことを意味します(通常はTCP/IP RST
パケットを送信することにより)。サードパーティのアプリケーションを使用している場合、考えられる原因は次のとおりです。
最初のケースは何が起こっているのでしょう。
Wireshark を起動して、ワイヤで何が起こっているかを正確に確認し、問題を絞り込むことができます。
より具体的な情報がなければ、ここの誰かが本当にあなたを大いに助けてくれることはまずありません。
TLS 1.2を使用してこのエラーを解決しました。
これでTLS 1.2を使用してアプリケーションを強制できます(サービスを呼び出す前に必ず実行してください)。
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
別のソリューション:
TLS1.2を使用するには、デフォルトで無効になっているため、TLS1.0のみが使用されるため、ローカルマシンまたはサーバーで強力な暗号化を有効にします。
強力な暗号化を有効にするには、管理者権限でPowerShellで次のコマンドを実行します。
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
これらの変更を有効にするには、コンピューターを再起動する必要があります。
これはコードのバグではありません。 .NetのSocket実装から来ています。以下のようにEndReceiveのオーバーロード実装を使用する場合、この例外は発生しません。
SocketError errorCode;
int nBytesRec = socket.EndReceive(ar, out errorCode);
if (errorCode != SocketError.Success)
{
nBytesRec = 0;
}
この一般的な迷惑な問題の簡単な解決策:
「。context.cs」ファイル(「* .edmx」ファイルの下にある「。context.tt」の下)に移動します。
次に、この行をコンストラクタに追加します。
public DBEntities()
: base("name=DBEntities")
{
this.Configuration.ProxyCreationEnabled = false; // ADD THIS LINE !
}
これが役立つことを願っています。
同じバグがありました。トラフィックがプロキシ(私の場合はフィドラー)を使用して送信された場合に実際に機能しました。 .NETフレームワークを4.5.2から4.6以上に更新し、すべてが正常に機能するようになりました。実際の要求は次のとおりです。new WebClient().DownloadData("URL");
例外は次のとおりです。
SocketException:既存の接続がリモートホストによって強制的に閉じられました
エンティティの循環参照のためにこの例外があります
public class Catalog
{
public int Id { get; set; }
public int ParentId { get; set; }
public Catalog Parent { get; set; }
public ICollection<Catalog> ChildCatalogs { get; set; }
}
Parentプロパティに[IgnoreDataMemberAttribute]を追加しました。そしてそれは問題を解決しました。
クラスのDateTimeプロパティが値を取得していないときに、この例外に遭遇しました。
public class PlanningBoardBO
{
... Other Properties ...
public DateTime? PickupDate { get; set; }
... Here changed DateTime to DateTime?
}
。Net 4.5.2サービスで実行している場合
私にとっては、呼び出しが.Net 4.5.2サービスで実行されていたため、問題はさらに悪化しました。 @willmazの提案に従いましたが、新しいエラーが発生しました。
ロギングをオンにしてサービスを実行すると、ターゲットサイトとのハンドシェークがokを開始する(およびベアラートークンを送信する)ことを確認しましたが、Post呼び出しを処理する次のステップでは、認証トークンがドロップされ、サイトがUnauthorized
で返信します。
サービスプールの資格情報にはTLS(?)を変更する権限がなく、ローカル管理者アカウントをプールに入れると、すべて正常に機能することがわかりました。
私は同じ問題を抱えていたが、結局それを解決することができた。私の場合、クライアントがリクエストを送信するポートには、SSL証明書がバインドされていませんでした。そこで、サーバー側のポートにSSL証明書をバインドすることで問題を修正しました。それが完了すると、この例外はなくなりました。