Impossibile leggere i dati dalla connessione di trasporto: una connessione esistente è stata chiusa forzatamente dall'host remoto


103

Ho un'app server e talvolta, quando il client tenta di connettersi, ricevo il seguente errore:

inserisci qui la descrizione dell'immagine

NOTA: "Impossibile ottenere lo streaming dal client o accesso non riuscito" è un testo aggiunto da me nell'istruzione catch

e la riga alla quale si ferma (sThread: riga 96) è:

tcpClient = (TcpClient)client;
clientStream = tcpClient.GetStream();
sr = new StreamReader(clientStream);
sw = new StreamWriter(clientStream);

// line 96:                 
a = sr.ReadLine();

Cosa potrebbe causare questo problema? Nota che non succede sempre

Risposte:


63

Questo errore di solito indica che la macchina di destinazione è in esecuzione, ma il servizio a cui stai tentando di connetterti non è disponibile. (O si è fermato, si è bloccato o è occupato con un'altra richiesta.)

In inglese: la connessione alla macchina (host remoto / server / PC su cui viene eseguito il servizio) è stata effettuata ma poiché il servizio non era disponibile su quella macchina, la macchina non sapeva cosa fare con la richiesta.

Se la connessione alla macchina non era disponibile, vedresti un errore diverso. Ho dimenticato cosa sia, ma è sulla falsariga di "Servizio irraggiungibile" o "Non disponibile".

Modifica - aggiunto

È possibile che ciò sia causato da un firewall che blocca la porta, ma dato che dici che è intermittente ("a volte quando il client tenta di connettersi"), è molto improbabile. Inizialmente non l'ho incluso perché l'avevo escluso mentalmente prima di rispondere.


1
il fatto è che quando avvio il server ci sono circa 50 client che si connettono al mio server. Ho implementato una sorta di segnale di attesa quando si accetta un client .. qualcosa come while (Program.waitToFinishLoginAtClient == true && ajutor <30) {Thread.Sleep (300); ajutor ++; } client = this.tcpListener.AcceptTcpClient (); Program.waitToFinishLoginAtClient = true; ........... e Program.waitToFinishAtClient viene modificato nel thread che contiene il client
Alex

questa "attesa" potrebbe essere il problema?
Alex

1
dovrei lasciare che sia? non aspettare ?
Alex

1
Penso che l'attesa sia il problema. Non so abbastanza del tuo codice per esserne sicuro, ma sicuramente sembra probabile. Sono solo curioso di sapere se hai costruito il tuo servizio nel "modo più duro" o se stai usando WCF o anche Remoting per questo ...
David

Sulla base del piccolo pignolo di codice qui, mi sembra che il problema di "attesa" potrebbe essere evitato se fosse all'interno di un thread separato per ogni connessione. Nel caso in cui l'ipotesi sia corretta, ecco un esempio di un servizio TCP multi-thread con multi-threading che potrebbe aiutarti: switchonthecode.com/tutorials/…
David

180

Ho ricevuto questo errore quando ho chiamato un servizio web. Il problema riguardava anche la sicurezza a livello di trasporto. Potrei chiamare il servizio Web tramite un progetto di sito Web, ma riutilizzando lo stesso codice in un progetto di test otterrei un'eccezione WebException che conteneva questo messaggio. L'aggiunta della seguente riga prima di effettuare la chiamata ha risolto il problema:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

modificare

System.Net.ServicePointManager.SecurityProtocol : questa proprietà seleziona la versione del protocollo SSL (Secure Sockets Layer) o TLS (Transport Layer Security) da utilizzare per le nuove connessioni che utilizzano solo lo schema HTTPS (Secure Hypertext Transfer Protocol); le connessioni esistenti non vengono modificate.

Credo che la SecurityProtocolconfigurazione sia importante durante l'handshake TLS quando si seleziona la versione del protocollo.

Handshake TLS : questo protocollo viene utilizzato per scambiare tutte le informazioni richieste da entrambe le parti per lo scambio dei dati dell'applicazione effettiva da parte di TLS.

ClientHello : un client invia un messaggio ClientHello specificando la versione del protocollo TLS più alta che supporta ...

ServerHello - Il server risponde con un messaggio ServerHello, contenente la versione del protocollo scelta ... La versione del protocollo scelta dovrebbe essere la più alta supportata sia dal client che dal server. Ad esempio, se il client supporta TLS versione 1.1 e il server supporta la versione 1.2, è necessario selezionare la versione 1.1; la versione 1.2 non dovrebbe essere selezionata.


8
questo mi ha salvato! grazie uomo. nel mio debugger sto cercando di chiamare un servizio https durante il test e ho riscontrato il problema che stava avendo l'OP.
Blair Holmes

6
Sappiamo di più su come / perché funziona? Ho lottato con una chiamata PostAsync e questo sembra correggere anche il mio errore. Sono contento che abbia funzionato, ma vorrei anche sapere perché.
Kevin Matlock

1
@HansVonn Grazie per questo! Mi ha fatto risparmiare un sacco di tempo - Riguardo al motivo per cui funziona, limita solo la versione TLS che stai utilizzando quando ti connetti.
confuso e

1
Non posso credere che questo mi abbia catturato ancora una volta! Grazie
Sergio A.

2
GRAZIE! Questo mi stava facendo impazzire.
mknopf

34

Il mio caso specifico scenario era che il servizio app di Azure aveva la versione TLS minima modificata in 1.2

Non so se è l'impostazione predefinita d'ora in poi, ma cambiarlo di nuovo a 1.0 lo ha fatto funzionare.

È possibile accedere alle impostazioni all'interno di "Impostazioni SSL".


7
Oh mio dio GRAZIE MOLTO! Sono rimasto bloccato su questo per così tanto tempo e ho controllato le impostazioni SSL dell'app Web e il minimo era impostato su 1.2 invece di 1.0. Quando l'ho modificato di nuovo in 1.0 e ho riavviato l'app Web, ha funzionato! Grazie mille!
Mason

1
Grazie mille, @ hugo-hilário, sorprendentemente ha funzionato anche per me! Come diavolo sei riuscito a trovare una soluzione così complicata! : D
hosjay

@hosjay è stato un inferno anche per me :)
Hugo Hilário

3
Ho salvato il mio compagno di giornata!
Nitesh


17

Non sono sicuro di quale delle correzioni in questi post del blog abbia aiutato, ma una di loro ha risolto questo problema per me ...

http://briancaos.wordpress.com/2012/07/06/unable-to-read-data-from-the-transport-connection-the-connection-was-closed/

Il trucco che mi ha aiutato è stato quello di smettere di usare un WebRequest e utilizzare invece un HttpWebRequest. HttpWebRequest mi permette di giocare con 3 importanti impostazioni:

e

http://briancaos.wordpress.com/2012/06/15/an-existing-connection-was-forcibly-closed-by-the-remote-host/

  • PASSAGGIO 1: disabilitare KeepAlive
  • PASSAGGIO 2: impostare ProtocolVersion su Version10
  • FASE 3: Limitare il numero di punti di servizio

1
Questa risposta è ciò che ha risolto questo stesso problema per me. Ho disattivato "Keep Alive" nella sezione Http Response Headers in IIS7
drzounds

Devo aggiungere che ho anche dovuto aggiungere questo codice a Reference.cs per il servizio Web che aveva quel comportamento. sovrascrittura protetta System.Net.WebRequest GetWebRequest (Uri uri) {System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest) base.GetWebRequest (uri); webRequest.KeepAlive = false; return webRequest; }
drzounds

11

Anche le chiamate ai servizi HTTPS da uno dei nostri server generavano l' eccezione " Impossibile leggere i dati dalla connessione di trasporto: una connessione esistente è stata chiusa forzatamente ". Il servizio HTTP, tuttavia, ha funzionato bene. Ho utilizzato Wireshark per vedere che si trattava di un errore di handshake TLS. Alla fine è stato necessario aggiornare la suite di cifratura sul server.


Questo è quello che stava succedendo con me. A stava inviando un certificato scaduto a una connessione SSL. A rinnovare il certificato e ha funzionato.
Guilherme de Jesus Santos

8

Secondo "Hans Vonn" risponde.

L'aggiunta della seguente riga prima di effettuare la chiamata ha risolto il problema:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Dopo aver aggiunto il protocollo di sicurezza e aver funzionato bene, ma devo aggiungere prima di ogni chiamata API che non è salutare. Ho appena aggiornato la versione di .net framework almeno 4.6 e lavorando come previsto non è necessario aggiungere prima di ogni chiamata API.


1
Grazie mille. hai reso la mia giornata. Potrebbe essere utile per alcuni se menziono che prima di questo ho anche testato la disattivazione del firewall e l'aggiunta di ServicePointManager.ServerCertificateValidationCallback ma non ha funzionato.
Tekin

5

Questo non aiuta per problemi intermittenti, ma può essere utile per altre persone con un problema simile.

Avevo clonato una VM e l'ho avviata su una rete diversa con un nuovo indirizzo IP ma non ho modificato i collegamenti in IIS. Fiddler mi mostrava "Impossibile leggere i dati dalla connessione di trasporto: una connessione esistente è stata chiusa forzatamente dall'host remoto" e IE mi diceva "Attiva TLS 1.0, TLS 1.1 e TLS 1.2 nelle impostazioni avanzate". La modifica dell'associazione al nuovo indirizzo IP ha risolto il problema.


2

Per qualche motivo, la connessione al server è stata persa. Potrebbe essere che il server abbia chiuso esplicitamente la connessione o un bug sul server ne abbia causato la chiusura inaspettata. O qualcosa tra il client e il server (uno switch o un router) ha interrotto la connessione.

Potrebbe essere il codice del server che ha causato il problema e potrebbe non esserlo. Se hai accesso al codice del server, puoi inserire un po 'di debug per dirti quando le connessioni client sono chiuse. Questo potrebbe darti qualche indicazione su quando e perché le connessioni vengono interrotte.

Sul client, devi scrivere il tuo codice per tenere conto della possibilità che il server si guasti in qualsiasi momento. È proprio così: le connessioni di rete sono intrinsecamente inaffidabili.


2

Questo ha risolto il mio problema. Ho aggiunto questa riga prima della richiesta:

System.Net.ServicePointManager.Expect100Continue = false;

Sembrava ci fosse un proxy nel modo in cui il server non supportava il comportamento di 100 continue.


1

Ho avuto quel problema in passato. Sto usando PostgreSQL e quando eseguo il mio programma, a volte si connette e talvolta genera un errore del genere.

Quando provo con il mio codice, inserisco il mio codice di connessione nella prima riga sotto il modulo pubblico. Ecco un esempio:

PRIMA:

    public Form1()
        {
        //HERE LIES SOME CODES FOR RESIZING MY CONTROLS DURING RUNTIME
        //CODE
        //CODE AGAIN
        //ANOTHER CODE
        //CODE NA NAMAN
        //CODE PA RIN!





        //Connect to Database to generate auto number
        NpgsqlConnection iConnect = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Password=pass;Database=DB");
        iConnect.Open();
        NpgsqlCommand iQuery = new NpgsqlCommand("Select * from table1", iConnect);
        NpgsqlDataReader iRead = iQuery.ExecuteReader();
        NpgsqlDataAdapter iAdapter = new NpgsqlDataAdapter(iQuery);

        DataSet iDataSet = new DataSet();
        iAdapter.Fill(iDataSet, "ID");

        MessageBox.Show(iDataSet.Tables["ID"].Rows.Count.ToString());
        }

ADESSO:

    public Form1()
        {
        //Connect to Database to generate auto number
        NpgsqlConnection iConnect = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Password=pass;Database=DB");
        iConnect.Open();
        NpgsqlCommand iQuery = new NpgsqlCommand("Select * from table1", iConnect);
        NpgsqlDataReader iRead = iQuery.ExecuteReader();
        NpgsqlDataAdapter iAdapter = new NpgsqlDataAdapter(iQuery);

        DataSet iDataSet = new DataSet();
        iAdapter.Fill(iDataSet, "ID");

        MessageBox.Show(iDataSet.Tables["ID"].Rows.Count.ToString());





        //HERE LIES SOME CODES FOR RESIZING MY CONTROLS DURING RUNTIME
        //CODE
        //CODE AGAIN
        //ANOTHER CODE
        //CODE NA NAMAN
        //CODE PA RIN!

        }

Penso che il programma debba leggere prima la connessione prima di fare qualsiasi cosa, non lo so, correggimi se sbaglio. Ma secondo la mia ricerca, non è un problema di codice: in realtà proveniva dalla macchina stessa.

Buona programmazione!


1
System.Net.ServicePointManager.Expect100Continue = false;

Questo problema a volte si verifica a causa del server proxy implementato sul server web. Per bypassare il server proxy inserendo questa riga prima di chiamare il servizio di invio.


0

Avevo un'applicazione di terze parti (Fiddler) in esecuzione per provare a vedere le richieste inviate. La chiusura di questa applicazione ha risolto il problema per me


0

Si è verificato un problema molto simile per cui il sito Web di un cliente tentava di connettersi al nostro servizio API Web e riceveva lo stesso messaggio. Ciò ha iniziato ad accadere completamente all'improvviso quando non c'erano state modifiche al codice o aggiornamenti di Windows sul server in cui era in esecuzione IIS.

Nel nostro caso si è scoperto che il sito Web chiamante utilizzava una versione di .Net che supportava solo TLS 1.0 e per qualche motivo il server su cui era in esecuzione il nostro IIS si è interrotto sembrava aver smesso di accettare chiamate TLS 1.0. Per diagnosticare che abbiamo dovuto abilitare esplicitamente TLS tramite il registro sul server IIS e quindi riavviare quel server. Queste sono le chiavi di registro:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.0\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.0\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.1\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.1\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.2\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.2\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

If that doesn't do it, you could also experiment with adding the entry for SSL 2.0:


    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
    "DisabledByDefault"=dword:00000000
    "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
    "DisabledByDefault"=dword:00000000
    "Enabled"=dword:00000001

La mia risposta a un'altra domanda qui ha questo script PowerShell che abbiamo usato per aggiungere le voci:

NOTA: Abilitare i vecchi protocolli di sicurezza non è una buona idea, la risposta giusta nel nostro caso è stata quella di far sì che il sito Web del client aggiorni il suo codice per utilizzare TLS 1.2, ma le voci di registro di cui sopra possono aiutare a diagnosticare il problema in primo luogo.


0

Il motivo per cui mi stava succedendo era che avevo una dipendenza ricorsiva nel mio provider DI. Nel mio caso ho avuto:

services.AddScoped(provider => new CfDbContext(builder.Options));
services.AddScoped(provider => provider.GetService<CfDbContext>());

La correzione consisteva nel rimuovere solo la seconda registrazione del servizio con ambito

services.AddScoped(provider => new CfDbContext(builder.Options));

0

Se hai un certificato https sul dominio, assicurati di avere l'associazione https al nome di dominio in IIS. In IIS -> Seleziona il tuo dominio -> Fai clic su Binding Site Bindings Window si apre. Aggiungi un'associazione per https.


0

Ho avuto un problema simile e ricevevo i seguenti errori a seconda dell'app che ho usato e se abbiamo aggirato o meno il firewall / bilanciamento del carico:

Handshake HTTPS a [blah] (per # 136) non riuscito. System.IO.IOException Impossibile leggere i dati dalla connessione di trasporto: una connessione esistente è stata chiusa forzatamente dall'host remoto

e

ReadResponse () non riuscita: il server non ha restituito una risposta completa per questa richiesta. Il server ha restituito 0 byte.

Il problema si è scoperto essere che il certificato del server SSL è stato perso e non è stato installato su un paio di server.


0

Prova a controllare se riesci a stabilire la stretta di mano in primo luogo. Ho avuto questo problema prima durante il caricamento di un file e ho capito che il problema era il percorso inesistente solo quando ho rimosso il caricamento e ho verificato se è possibile accedere ai parametri.



0

Per me, era un problema in cui nell'associazione IIS aveva l'indirizzo IP del server web. L'ho cambiato per utilizzare tutti gli IP non assegnati e la mia applicazione ha iniziato a funzionare.


0

Ho riscontrato l'errore con python clr che esegue query mdx ai servizi di analisi Microsoft utilizzando adomd

L'ho risolto con l'aiuto di Hans Vonn ed ecco la versione python :

clr.AddReference("System.Net")
from System.Net import ServicePointManager, SecurityProtocolType 
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls

0

Per coloro che potrebbero trovarlo in seguito, dopo la versione .NET 4.6, ho riscontrato anche questo problema.

Assicurati di controllare il tuo file web.config per le seguenti righe:

<compilation debug="true" targetFramework="4.5">
...
<httpRuntime targetFramework="4.5" />

Se stai eseguendo 4.6.xo una versione successiva di .NET sul server, assicurati di regolare questi valori targetFramework in modo che corrispondano alla versione del framework sul tuo server. Se le tue versioni leggono meno di 4.6.x, ti consiglio di aggiornare .NET e utilizzare la versione più recente a meno che il tuo codice non dipenda da una versione precedente (che, in tal caso, dovresti considerare di aggiornarla).

Ho cambiato targetFrameworks in 4.7.2 e il problema è scomparso:

<compilation debug="true" targetFramework="4.7.2">
...
<httpRuntime targetFramework="4.7.2" />

I framework più recenti risolvono questo problema utilizzando il miglior protocollo disponibile e bloccando quelli non sicuri o obsoleti. Se il servizio remoto a cui si sta tentando di connettersi o che si chiama dà questo errore, è possibile che non supportino più i vecchi protocolli.

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.