web-dev-qa-db-ja.com

既存の接続がリモートホストによって強制的に閉じられました

古いasmxスタイルのWebサービスを使用している太いVB.NET Winformクライアントがあります。非常に頻繁に、しばらく時間がかかるクエリを実行したり、大量のデータをデータセット内のWebサービスに渡したりすると、件名エラーが発生します。

エラーは1分未満で発生しているようです。これは、設定したWebサービスのタイムアウト値またはADO Web内でクエリを実行しているCommandオブジェクトのタイムアウト値よりもはるかに小さい値です。サーバ。

大量の行を返すことが予想される大規模なクエリを実行しているとき、またはWebサービスに大量のデータを送信しているときに発生するようです。たとえば、大規模なデータセットをWebサーバーに渡したときに発生しました。

System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote Host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote Host
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   --- End of inner exception stack trace ---
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)
   --- End of inner exception stack trace ---
   at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request)
   at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
   at Smit.Pipeline.Bo.localhost.WsSR.SaveOptions(String emailId, DataSet dsNeighborhood, DataSet dsOption, DataSet dsTaskApplications, DataSet dsCcUsers, DataSet dsDistinctUsers, DataSet dsReferencedApplications) in C:\My\Code\Pipeline2\Smit.Pipeline.Bo\Web References\localhost\Reference.vb:line 944
   at Smit.Pipeline.Bo.Options.Save(TaskApplications updatedTaskApplications) in 

私はこのエラーに関するたくさんの投稿を探していましたが、このエラーの原因となる状況がどれほど多様であるかは驚くべきことです。私はWiresharkをいじってみましたが、それを使用する方法がわかりません。

このアプリケーションには一度に約20人のユーザーしかいませんが、おそらく誰もアプリを使用していない真夜中にこのエラーを再現できます。そのため、Webサーバーへのリクエストの数やデータベースへの高いです。たぶん私はおそらく今このアプリを使用している唯一の人であり、今はエラーが発生しました。いずれかの方向に渡される大量のデータですべてを行う必要があるようです。

このエラーは本当に慢性的で、私を殺しています。助けてください。

9
ChadD

クライアントのapp.configバインディング設定を確認し、最大メッセージサイズを指定しているかどうかを確認してください。これのデフォルト値は65536です

これを変更するには、app.configでバインディング構成に配置するか(maxReceivedMessageSize、maxBufferSize、maxArrayLengthがこの主要なプロパティです)、またはプログラムでバインディングのプロパティを変更して、次のようにします。

System.ServiceModel.BasicHttpBinding binding = new System.ServiceModel.BasicHttpBinding();

// if you are getting a LOT of data back, you will need to up Message Size
binding.MaxReceivedMessageSize = int.MaxValue; 

これで問題が解決しない場合は、サーバー側のイベントログで詳細を確認する必要があります。メッセージは、クライアントが接続が閉じることを予期していなかったが、それが閉じたことを意味し、それは多くの異なることを意味する可能性があります。

可能であれば、WebサービスにWCFを使用します。 ASMXサービスが依然として苦しんでいる多くの問題を解決します。

サーバー側の送信制限と実行タイムアウトを増やすには、これを使用します

<configuration>
  <system.web> 
    <httpRuntime maxMessageLength="409600" executionTimeoutInSeconds="300"/> 
  </system.web>
</configuration> 
2
Greg Olmstead

私はまったく同じ問題を抱えていました。 Webサービスの呼び出しは、同じ断続的な例外(〜1日1回)で失敗します。これは、大きすぎるパケットサイズや小さすぎるタイムアウトには関連していませんでした。

問題を回避するための再試行ロジックを追加しただけです。参照: この例外再試行シナリオをどのように改善できますか?

2
robbie

このコードは私のために問題を解決しました:

Socket.ReceiveFrom(Buffer, Net.Sockets.SocketFlags.None, ReceiveEndpoint)
Socket.SendTo(Buffer, Length, Net.Sockets.SocketFlags.None, ReceiveEndpoint)

socketsflagsで関数を使用したときに、サーバー/クライアントが再び切断されませんでした。

私の場合、汎用のHTTPハンドラー(handler.ashx)でWCFサービスから大きなファイルを取得しようとすると、予期せず接続が切断されていました。結局のところ、答えは1つのMicrosoft Webページ( https://msdn.Microsoft.com/en-us/library/ms733742.aspx )とMicrosoftへの呼び出しで届きました。そのページの1つの重要な項目のスペルが間違っていました(「ストリーミング」ではなく「ストリーミング」である必要があります)。 WCFサービスのapp.configファイルに適用された、そのページからの修正されたコードスニペットは次のとおりです。

<system.serviceModel>
<bindings>
    ...
    <basicHttpBinding>
    <binding name="ExampleBinding" transferMode="Streamed"/>
        </basicHttpBinding>
    </bindings>
    ...
<system.serviceModel>

重要なのは、転送モードを設定することでした。

1

ASP.NETの場合、web.configファイルでmaxRequestLengthをより高い値に設定してみてください

<httpRuntime maxRequestLength="65536"/>

アクセス拒否などの他のエラーが発生する可能性があるため、値を大きくしすぎないでください。リモートサーバーへのデータアップロードの場合は、データをスライスしてチャンクで送信してみてください。

敬具、

マファズ

1
sm2mafaz

IIS 7(私の場合)の場合、WebサービスのアプリケーションプールのIDは "ApplicationPoolIdentity"でした。ローカルユーザーに割り当てたところ、問題なく動作しました。

0
user007

はい、同じエラーが発生しました。しかし私の場合、問題はAVソフトウェアにあり、レポートサービスをローカルでブロックしていました。

0
Andrew Kostenko

これを試してみて、ネットワークストリーム経由で送信された10000のために私のために働きます

defind SendBufferSize現在のTcpClientの設定よりも大きいか、または値が定義されていない場合はシステムに最適化して8192にすると、これ以上バイトを送信できなくなります。

** YourInstantTcpClient**.SendBufferSize = 6550000

申し訳ありませんが、私はタイ人です。私の英語が下手かもしれません。

0
mezz