WebService に対して HttpWebRequest を実行しているときに、次のエラーが発生することがあります。以下のコードもコピーしました。
System.Net.WebException: リモート サーバーに接続できません ---> System.Net.Sockets.SocketException: ターゲット マシンが積極的に拒否したため、接続できませんでした 127.0.0.1:80 System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot、SocketAddress socketAddress) で System.Net.Sockets.Socket.InternalConnect(エンドポイント remoteEP) で System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure、Socket s4、Socket s6、Socket& socket、IPAddress& address、ConnectSocketState state、IAsyncResult asyncResult、Int32 timeout、Exception& exception) で --- 内部例外スタック トレースの終了 --- System.Net.HttpWebRequest.GetRequestStream() で
ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.PreAuthenticate = true;
request.Credentials = networkCredential(sla);
request.Method = WebRequestMethods.Http.Post;
request.ContentType = "application/x-www-form-urlencoded";
request.Timeout = v_Timeout * 1000;
if (url.IndexOf("asmx") > 0 && parStartIndex > 0)
{
AppHelper.Logger.Append("#############" + sla.ServiceName);
using (StreamWriter reqWriter = new StreamWriter(request.GetRequestStream()))
{
while (true)
{
int index01 = parList.Length;
int index02 = parList.IndexOf("=");
if (parList.IndexOf("&") > 0)
index01 = parList.IndexOf("&");
string parName = parList.Substring(0, index02);
string parValue = parList.Substring(index02 + 1, index01 - index02 - 1);
reqWriter.Write("{0}={1}", HttpUtility.UrlEncode(parName), HttpUtility.UrlEncode(parValue));
if (index01 == parList.Length)
break;
reqWriter.Write("&");
parList = parList.Substring(index01 + 1);
}
}
}
else
{
request.ContentLength = 0;
}
response = (HttpWebResponse)request.GetResponse();
ベストアンサー1
これが常に発生する場合、文字通り、マシンは存在するが、指定されたポートでリッスンしているサービスがないか、ファイアウォールによってブロックされていることを意味します。
それが時々発生し (「時々」という言葉を使用しました)、再試行が成功する場合には、サーバーの「バックログ」がいっぱいになっていることが原因である可能性があります。
リスニング ソケットで edされるのを待っている間accept
、バックログに置かれます。このバックログは有限で非常に短いです (1、2、または 3 の値は珍しくありません)。そのため、OS は、'accept' が消費するための要求をキューに入れることができない可能性があります。
バックログは関数のパラメータですlisten
。この点に関しては、すべての言語とプラットフォームで基本的に同じAPIがあります。C# 1 つ. このパラメータは、サーバーを制御している場合は構成可能であることが多く、設定ファイルまたはレジストリから読み取られる可能性があります。サーバーを構成する方法を調べてください。
サーバーを自分で書いた場合、ソケットの accept で大量の処理が行われる可能性があります。この処理は別のワーカー スレッドに移動した方が、accept が常に接続を受信できる状態になります。クライアントをキューに入れて順番に処理する負担を軽減する、さまざまなアーキテクチャの選択肢があります。
サーバーのバックログを増やすことができるかどうかに関係なく、この問題に対処するにはクライアント コードに再試行ロジックが必要です。バックログが長い場合でも、その時点でサーバーはそのポートで他の多くの要求を受信している可能性があるためです。
マッピング用のポートが使い果たされた場合、NAT ルーターがこのエラーを返す可能性はまれにあります。ただし、使い果たされるまでにルーターは同じ宛先アドレス/ポートに 64K の同時接続があるため、この可能性は低すぎるため、無視できると思います。