Una connessione esistente è stata forzatamente chiusa dall'host remoto


159

Sto lavorando con un'applicazione commerciale che sta generando una SocketException con il messaggio,

Una connessione esistente è stata forzatamente chiusa dall'host remoto

Ciò accade con una connessione socket tra client e server. La connessione è viva e vegeta e un sacco di dati viene trasferito, ma poi viene disconnesso dal nulla.

Qualcuno l'ha mai visto prima? Quali potrebbero essere le cause? Posso indovinare alcune cause, ma c'è anche un modo per aggiungere altro in questo codice per capire quale potrebbe essere la causa?

Eventuali commenti / idee sono benvenuti.

... L'ultimo ...

Ho delle registrazioni da alcune tracce di .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

Sulla base di altre parti della registrazione ho visto che dice "0 # 0" significa che viene inviato un pacchetto di 0 byte di lunghezza. Ma cosa significa veramente?

Si sta verificando una delle due possibilità e non sono sicuro di quale,

1) La connessione viene chiusa, ma i dati vengono quindi scritti nel socket, creando così l'eccezione sopra. Lo 0 # 0 significa semplicemente che non è stato inviato nulla perché il socket era già chiuso.

2) La connessione è ancora aperta e viene inviato un pacchetto di zero byte (ovvero il codice ha un bug) e lo 0 # 0 significa che un pacchetto di zero byte sta tentando di essere inviato.

Cosa ne pensi? Potrebbe essere inconcludente, immagino, ma forse qualcun altro ha visto questo genere di cose?


Solo un aggiornamento. Sembra che WireShark non lo taglierà in questo caso a causa della nostra configurazione di rete. Spero di provare questo, blogs.msdn.com/dgorti/archive/2005/09/18/471003.aspx che sta tracciando usando .NET che dovrebbe produrre alcuni file di registro. Ti terrò aggiornato ...
Pietro

1
comcast è anche noto per inviare pacchetti "zero" falsificati con ID falso per pasticciare con traffico p2p ---

Risposte:


98

Ciò significa generalmente che il lato remoto ha chiuso la connessione (di solito inviando un RSTpacchetto TCP / IP ). Se lavori con un'applicazione di terze parti, le cause probabili sono:

  • Stai inviando dati non validi all'applicazione (che potrebbe includere l'invio di una richiesta HTTPS a un server HTTP)
  • Il collegamento di rete tra client e server non funziona per qualche motivo
  • È stato attivato un bug nell'applicazione di terze parti che ha causato l'arresto anomalo
  • L'applicazione di terze parti ha esaurito le risorse di sistema

È probabile che il primo caso sia quello che sta succedendo.

Puoi accendere Wireshark per vedere esattamente cosa sta succedendo sul filo per restringere il problema.

Senza informazioni più specifiche, è improbabile che qualcuno qui possa davvero aiutarti molto.


2
Grande. Grazie. L'altra cosa su WireShark. Raccoglie così tanti dati, come potrei filtrare qualcosa del genere? Se WireShark mostra qualcosa che potrei postare qui più tardi ...
Pietro

4
Dovresti essere in grado di filtrare il dump di Wireshark per indirizzo IP e numero di porta, almeno. Dopodiché, è probabilmente molto utile guardare la fine del flusso (dove qualcosa è andato storto) e lavorare all'indietro fino a quando non si riesce a individuare dove le cose vengono prima incasinate. A seconda della complessità del protocollo coinvolto, può essere davvero facile quasi impossibile ...
RarrRarrRarr

4
Esiste una fonte per gli oggetti puntati o la risposta del giocatore qui sotto ha semplicemente copiato il tuo elenco?
Zack,

7
Si noti che "l'invio di dati non validi" potrebbe significare l'invio di una httpsrichiesta a un httpserver e probabilmente viceversa.
AXMIM,

2
Nel mio caso, ho ricevuto questa eccezione solo quando ho chiamato un'API quando eseguivo l'app localmente. Nessun problema negli ambienti dev, qa o prod. La correzione? Utilizzo di http anziché https localmente. Pensiamo che possa essere correlato a un bilanciamento del carico. Ma abbiamo appena aggiornato i nostri dev, qa e prod web.configs con trasformazioni per https. Problema risolto.
Kershaw,

82

L'uso di TLS 1.2 ha risolto questo errore.
È possibile forzare l'applicazione utilizzando TLS 1.2 con questo (assicurarsi di eseguirla prima di chiamare il servizio):

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 

Un'altra soluzione:
abilitare la crittografia avanzata nel computer o nel server locale per utilizzare TLS1.2 perché per impostazione predefinita è disabilitato, quindi viene utilizzato solo TLS1.0.
Per abilitare la crittografia avanzata, eseguire questi comandi in PowerShell con privilegi di amministratore:

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 

È necessario riavviare il computer per rendere effettive queste modifiche.


1
È possibile aggiungere più valori insieme per supportare più protocolli. Quindi per supportare tutto, da SSL3 a TLS1.2, imposta SecurityProtocol = (SecurityProtocolType) 4080.
Abacus

29

Questo non è un bug nel tuo codice. Viene dall'implementazione di .Net Socket. Se si utilizza l'implementazione sovraccarica di EndReceive come di seguito non si otterrà questa eccezione.

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

1
Questo proviene dal sistema operativo e, in definitiva, dal peer. Sono necessarie ulteriori spiegazioni sull'accusa che si tratta di un bug del software.
Marchese di Lorne,

5
+1. Nel mio programma C #, stavo sbattendo la testa sul motivo per cui si EndReceivesta gettando un'eccezione quando c'è una chiusura clientelare. Non sapevo che questo è di progettazione. Sento il suo cattivo design per gettare un'eccezione nei normali flussi di codice. Grazie a Dio per il metodo sovraccarico.
Pavan Manjunath,

2
@MSaudi Questo utilizza una chiamata asincrona, assicurarsi di comprendere che il codice non si arresterà durante l'elaborazione dei dati restituiti. L'esempio utilizza msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx . Fondamentalmente devi avere una StateObjectclasse con public byte[] buffer = new byte[1024], public Socket socket;e chiamare una funzione chiamata Receive(Socket s), che fa StateObject so = new StateObject(); so.socket = s; s.BeginReceive(so.buffer, 0, 256, 0, new AsyncCallback(ReceiveCallback), so); e in void ReceiveCallback(IAsyncResult ar)te chiama quel codice, sopra.
vapcguy,

2
@cagatay Sebbene offra una soluzione, non ho mai visto valore nei metodi asincroni in cui è necessario sapere subito cosa ritorna dopo aver fatto il tuo Sendprima di poter fare qualsiasi altra cosa.
vapcguy,

3
In realtà ho scoperto che questo metodo non è infallibile. Può anche causare l'errore del PO: stackoverflow.com/questions/17790612/...
vapcguy

10

Soluzione semplice per questo fastidioso problema comune:

Basta andare al file " .context.cs" (situato sotto " .context.tt" che si trova sotto il file "* .edmx").

Quindi, aggiungi questa riga al costruttore:

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

spero che sia utile


@Esi dove metterlo? e nessun tipo di ritorno ??
Khalil Khalaf,

2
@FirstStep: Coz questo è un costruttore.
Nikhil Agrawal,

3
Questo aiuta solo coloro che utilizzano Entity Framework a riscontrare il problema, non quelli che stanno facendo una socket.Send(x); byte[] buffer = new byte[1]; socket.Receive(buffer, 0, 1, 0);lettura semplice dei byte restituiti, che era il problema del PO.
vapcguy,

se usando ENTITY FRAMEWORKsolo questa soluzione funziona !!! solo questo ! grazie fratello :)
Rao Hammas,

9

Aveva lo stesso bug. In realtà ha funzionato nel caso in cui il traffico fosse inviato utilizzando un proxy (fiddler nel mio caso). Framework .NET aggiornato da 4.5.2 a> = 4.6 e ora tutto funziona bene. La richiesta effettiva era:
new WebClient().DownloadData("URL");
l'eccezione era:

SocketException: una connessione esistente è stata forzatamente chiusa dall'host remoto


5
Questo era un modo per risolvere le cose per me. In realtà era correlato alla versione di TLS .NET utilizzata per impostazione predefinita. 4.5.2 e versioni precedenti hanno utilizzato TLS 1.0, mentre 4.6 e versioni successive sono più intelligenti nel consentire 1.1 e 1.2. Ciò è stato dimostrato anche eliminando il requisito TLS sul server su 1.0, che ha risolto anche il problema.
HotN,

4

Ho questa eccezione a causa del riferimento circolare nell'entità. Nell'entità che assomiglia

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

Ho aggiunto [IgnoreDataMemberAttribute] alla proprietà Parent. E questo ha risolto il problema.


2

Se in esecuzione in un servizio .Net 4.5.2

Per me il problema è stato aggravato perché la chiamata era in esecuzione in un servizio .Net 4.5.2. Ho seguito il suggerimento di @willmaz ma ho ricevuto un nuovo errore.

Durante l'esecuzione del servizio con la registrazione attivata, ho visualizzato l'handshaking con il sito di destinazione che avvierebbe ok (e inviava il token al portatore) ma nel passaggio successivo per elaborare la chiamata post, sembrerebbe eliminare il token di autenticazione e il sito avrebbe rispondere con Unauthorized.

Si è scoperto che le credenziali del pool di servizi non avevano i diritti per modificare TLS (?) E quando ho inserito il mio account di amministratore locale nel pool, tutto ha funzionato.


2

Per chiunque ottenga questa eccezione durante la lettura dei dati dallo stream, ciò può essere d'aiuto. Stavo ottenendo questa eccezione durante la lettura di HttpResponseMessage in un ciclo come questo:

using (var remoteStream = await response.Content.ReadAsStreamAsync())
using (var content = File.Create(DownloadPath))
{
    var buffer = new byte[1024];
    int read;

    while ((read = await remoteStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
    {
        await content.WriteAsync(buffer, 0, read);
        await content.FlushAsync();
    }
}

Dopo qualche tempo ho scoperto che il colpevole era la dimensione del buffer, che era troppo piccola e non funzionava bene con la mia debole istanza di Azure. Ciò che ha aiutato è stato cambiare il codice in:

using (Stream remoteStream = await response.Content.ReadAsStreamAsync())
using (FileStream content = File.Create(DownloadPath))
{
    await remoteStream.CopyToAsync(content);
}

Il metodo CopyTo () ha una dimensione del buffer predefinita di 81920. Il buffer più grande ha accelerato il processo e gli errori si sono arrestati immediatamente, molto probabilmente perché la velocità di download complessiva è aumentata. Ma perché la velocità di download è importante nel prevenire questo errore?

È possibile disconnettersi dal server perché la velocità di download scende al di sotto della soglia minima consentita dal server. Ad esempio, nel caso in cui l'applicazione da cui si sta scaricando il file sia ospitata su IIS, può essere un problema con la configurazione di http.sys:

"Http.sys è lo stack di protocollo http utilizzato da IIS per eseguire la comunicazione http con i client. Ha un timer chiamato MinBytesPerSecond che è responsabile dell'uccisione di una connessione se la sua velocità di trasferimento scende al di sotto di una soglia di kb / sec. Per impostazione predefinita, tale soglia è impostato su 240 kb / sec. "

Il problema è descritto in questo vecchio blog post del team di sviluppo di TFS e riguarda specificamente IIS, ma potrebbe indirizzarti nella giusta direzione. Menziona anche un vecchio bug relativo a questo attributo http.sys: link

Nel caso in cui si stiano usando i servizi app di Azure e aumentare le dimensioni del buffer non elimini il problema, provare anche a ridimensionare il computer. Ti verranno assegnate più risorse inclusa la larghezza di banda della connessione.


0

Ho avuto lo stesso problema e alla fine sono riuscito a risolverlo. Nel mio caso, la porta a cui il client invia la richiesta non aveva un certificato SSL vincolante ad essa. Quindi ho risolto il problema associando un certificato SSL alla porta sul lato server. Fatto ciò, questa eccezione è scomparsa.


-1

Questo errore si è verificato nella mia applicazione con il protocollo CIP ogni volta che non ho inviato o ricevuto dati in meno di 10 secondi.

Ciò è stato causato dall'uso del metodo open forward. Puoi evitarlo lavorando con un altro metodo o installando una frequenza di aggiornamento inferiore ai 10 che mantengono la tua connessione forward-open.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.