web-dev-qa-db-fra.com

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

Je travaille avec une application commerciale qui lance une exception SocketException avec le message,

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

Cela se produit avec une connexion de socket entre le client et le serveur. La connexion est bien vivante et des tas de données sont en train d'être transférés, mais ils deviennent alors déconnectés de nulle part.

Est-ce que quelqu'un a déjà vu ça? Quelles pourraient être les causes? Je peux en quelque sorte deviner quelques causes, mais y a-t-il un moyen d'ajouter plus dans ce code pour déterminer ce que la cause pourrait être?

Tous les commentaires/idées sont les bienvenus.

... Le dernier ...

J'ai un peu de journalisation à partir de traçage .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

En me basant sur d'autres parties de la journalisation, j'ai constaté que «0 # 0» signifie qu'un paquet de 0 octets de longueur est envoyé. Mais qu'est-ce que cela signifie réellement?

Une des deux possibilités se présente, et je ne suis pas sûr de ce qui,

1) La connexion est en cours de fermeture, mais les données sont ensuite en cours d'écriture dans le socket, créant ainsi l'exception ci-dessus. Le 0 # 0 signifie simplement que rien n'a été envoyé car le socket était déjà fermé.

2) La connexion est toujours ouverte et un paquet de zéro octet est envoyé (c’est-à-dire que le code a un bogue) et le 0 # 0 signifie qu’un paquet de zéro octet tente d’être envoyé.

Qu'est-ce que tu en penses? Je suppose que cela pourrait ne pas être concluant, mais peut-être que quelqu'un d'autre a vu ce genre de chose?

89
peter

Cela signifie généralement que le côté distant a fermé la connexion (généralement en envoyant un paquet TCP/IP RST). Si vous travaillez avec une application tierce, les causes probables sont les suivantes:

  • Vous envoyez des données malformées à l'application
  • Le lien réseau entre le client et le serveur est en panne pour une raison quelconque
  • Vous avez déclenché un bogue dans l'application tierce qui a provoqué son crash
  • L'application tierce a épuisé les ressources système

Il est probable que le premier cas est ce qui se passe.

Vous pouvez lancer Wireshark pour voir exactement ce qui se passe sur le fil afin de réduire le problème.

Sans informations plus spécifiques, il est peu probable que quelqu'un ici puisse vraiment vous aider beaucoup.

71
RarrRarrRarr

L'utilisation de TLS 1.2 a résolu cette erreur.
Vous pouvez forcer votre application avec TLS 1.2 avec ceci (assurez-vous de l’exécuter avant d’appeler votre service): 

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 

Une autre solution :
Activez la cryptographie forte sur votre ordinateur ou serveur local pour pouvoir utiliser TLS1.2 car, par défaut, elle est désactivée, de sorte que seul TLS1.0 est utilisé.
Pour activer la cryptographie forte, exécutez ces commandes dans PowerShell avec les privilèges d’administrateur:

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 

Vous devez redémarrer votre ordinateur pour que ces modifications prennent effet.

25
willmaz

Ce n'est pas un bug dans votre code. Cela vient de l'implémentation de .Net Socket. Si vous utilisez l'implémentation surchargée de EndReceive comme indiqué ci-dessous, vous ne recevrez pas cette exception.

    SocketError errorCode;
    int nBytesRec = socket.EndReceive(ar, out errorCode);
    if (errorCode != SocketError.Success)
    {
        nBytesRec = 0;
    }
24
cagatay

Solution simple à ce problème récurrent: 

Allez simplement dans votre fichier " .context.cs" (situé sous ". Context.tt", situé sous votre fichier "* .edmx"). 

Ajoutez ensuite cette ligne à votre constructeur: 

public DBEntities() 
        : base("name=DBEntities") 
    { 
        this.Configuration.ProxyCreationEnabled = false; // ADD THIS LINE !
    }

j'espère que c'est utile. 

7
ayheber

J'ai cette exception à cause d'une référence circulaire dans entity.In entity qui ressemble à

public class Catalog
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public Catalog Parent { get; set; }
    public ICollection<Catalog> ChildCatalogs { get; set; }
}

J'ai ajouté [IgnoreDataMemberAttribute] à la propriété Parent. Et cela a résolu le problème.

1
Bazaleev Nikolay

J'ai rencontré cette exception, lorsque la propriété DateTime de la classe n'obtenait pas la valeur. Je la rend simplement nullable DateTime et la solution Found.

public class PlanningBoardBO
    {
        ... Other Properties ...

        public DateTime? PickupDate { get; set; }

        ... Here changed DateTime to DateTime?
    }
0
UJS

Si vous utilisez un service .Net 4.5.2

Pour moi, le problème était complexe car l'appel était exécuté dans un service .Net 4.5.2. J'ai suivi la suggestion de @willmaz mais une nouvelle erreur s'est produite. 

Lors de l’exécution du service avec la journalisation activée, j’ai vu que le protocole de connexion avec le site cible s’engagerait ok (et enverrait le jeton porteur), mais lors de l’étape suivante du traitement de l’appel Post, il semblerait que le jeton d’authentification soit abandonné et que le site répondez avec Unauthorized.

Il s'est avéré que les informations d'identification du pool de services n'avaient pas le droit de modifier TLS (?) Et lorsque j'ai mis mon compte d'administrateur local dans le pool, tout a fonctionné.

0
ΩmegaMan

J'ai eu le même problème et j'ai finalement réussi à le résoudre. Dans mon cas, le port auquel le client envoie la demande ne contenait pas de certificat SSL. J'ai donc résolu le problème en liant un certificat SSL au port côté serveur. Une fois que cela a été fait, cette exception est partie.

0
iefgnoix