web-dev-qa-db-fra.com

Une connexion existante a été fermée de force par l'hôte distant

J'ai un gros client Winform VB.NET qui utilise l'ancien service Web de style asmx. Très souvent, lorsque j'exécute une requête qui prend un certain temps ou que je transmets beaucoup de données à un service Web dans un ensemble de données, j'obtiens l'erreur de sujet.

L'erreur semble se produire dans moins d'une minute, ce qui est nettement inférieur à la valeur de délai d'attente du service Web que j'ai définie ou à la valeur de délai d'attente sur l'objet ADO Command qui exécute la requête sur le serveur Web.

Il semble que cela se produise chaque fois que j'effectue une requête volumineuse censée renvoyer un grand nombre de lignes ou lorsque j'envoie une grande quantité de données au service Web. Par exemple, cela vient de se produire lorsque je passais un jeu de données volumineux sur le serveur 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 

J'ai regardé des tonnes d'articles sur cette erreur et il est étonnant de constater à quel point les circonstances qui ont provoqué cette erreur sont variées. J'ai essayé de jouer avec Wireshark, mais je ne sais pas comment l'utiliser.

Cette application ne compte qu'environ 20 utilisateurs à la fois et je suis en mesure de reproduire cette erreur au milieu de la nuit lorsque personne ne l'utilise probablement. Je ne pense donc pas que le nombre de demandes adressées au serveur Web ou à la base de données est élevé. Je suis probablement la seule personne à utiliser l'application pour le moment et je viens de recevoir l'erreur maintenant. Il semble avoir à tout faire avec la quantité de données transmises dans les deux sens.

Cette erreur est vraiment chronique et me tue. S'il vous plaît aider.

9
ChadD

Vérifiez le paramètre de liaison app.config de votre client et voyez si vous avez spécifié une taille maximale de message. La valeur par défaut est 65536

Pour changer cela, insérez-le dans votre configuration de liaison (maxReceivedMessageSize, maxBufferSize et maxArrayLength sont des propriétés clés pour cela) dans votre app.config, ou par programme en modifiant la propriété sur la liaison, comme ceci

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; 

Si cela ne résout pas votre problème, vous devrez vérifier le journal des événements côté serveur pour plus de détails. Le message signifie que le client ne s’attendait pas à ce que la connexion soit fermée, mais c’est le cas et cela peut vouloir dire beaucoup de choses différentes.

Si possible, utilisez WCF pour les services Web. Il résout de nombreux problèmes dont souffrent toujours les services ASMX.

Pour augmenter la limite de transmission côté serveur et le délai d’exécution, utilisez cette

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

J'avais exactement le même problème. Les appels de service Web échoueraient avec la même exception intermittente (~ une fois par jour). Cela n'était pas lié à des tailles de paquet trop grandes ni à des délais trop courts.

J'ai fini par mettre en place une logique de nouvelle tentative permettant de résoudre le problème. Voir: Comment puis-je améliorer ce scénario de nouvelle tentative d'exception?

2
robbie

Ce code a résolu le problème pour moi:

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

Lorsque j'ai utilisé la fonction avec socketsflags, le serveur/client n'a pas été déconnecté à nouveau.

2

Dans mon cas, mon gestionnaire HTTP générique (handler.ashx) rencontrait la connexion interrompue de manière inattendue lors de la tentative de récupération de fichiers volumineux à partir d'un service WCF. À la fin, la réponse est apparue sur une page Web de Microsoft ( https://msdn.Microsoft.com/en-us/library/ms733742.aspx ) et un appel à Microsoft, qui m’avait dit que cet élément critique sur cette page a été mal orthographié (aurait dû être "Streamed" au lieu de "Streaming"). L'extrait de code corrigé de cette page, appliqué au fichier app.config de mon service WCF, est le suivant:

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

La clé était de définir le mode de transfert.

1
Paul H. Harder II

Si c'est ASP.NET, essayez de définir maxRequestLength sur une valeur plus élevée dans le fichier web.config.

<httpRuntime maxRequestLength="65536"/>

N'augmentez pas trop la valeur car cela pourrait entraîner d'autres erreurs telles que le refus d'accès, etc. S'il s'agit d'un transfert de données sur un serveur distant, essayez de couper les données en tranches et de les envoyer en morceaux.

Sincères amitiés,

Mafaz

1
sm2mafaz

Pour IIS 7 (dans mon cas), l'identité du pool d'applications du service Web était "ApplicationPoolIdentity". J'ai assigné à un utilisateur local et cela a fonctionné très bien. 

0
user007

Ok, j'ai la même erreur. Mais dans mon cas, le problème provenait du logiciel antivirus, qui bloquait les services de génération de rapports localement.

0
Andrew Kostenko

essayez ceci, ça marche pour moi pour 10000 envoyés via un flux réseau 

defind SendBufferSize plus que la configuration du TcpClient actuel ou l’optimiser sur votre système sinon définir la valeur est 8192 ce qui signifie que vous ne pouvez pas envoyer plus d’octets que cela.

**YourInstantTcpClient**.SendBufferSize = 6550000 

Désolé, je suis thai, que mon anglais ne soit pas bon.

0
mezz