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

Ho un’app server e, a volte, quando il client tenta di connettersi, ottengo il seguente errore:

inserisci la descrizione dell'immagine qui

NOTA: il messaggio “Imansible ottenere il stream dal client o l’accesso non riuscito” è un testo che è stato aggiunto da me nell’istruzione catch

e la linea a cui si ferma (sThread: riga 96) è:

tcpClient = (TcpClient)client; clientStream = tcpClient.GetStream(); sr = new StreamReader(clientStream); sw = new StreamWriter(clientStream); // line 96: a = sr.ReadLine(); 

Quale potrebbe essere la causa di questo problema? Nota che non succede sempre

Questo errore di solito significa che il computer di destinazione è in esecuzione, ma il servizio a cui stai tentando di connettersi non è disponibile. (O si è fermato, si è bloccato o è occupato con un’altra richiesta.)

In inglese: la connessione alla macchina (host / server / PC remoto in 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 fosse disponibile, vedresti un errore diverso. Ho dimenticato di cosa si tratta, ma è sulla falsariga di “Service Unreachable” o “Unavailable”.

Modifica – aggiunto

È ansible che questo sia causato da un firewall che blocca la porta, ma dato che si dice che è intermittente (“a volte quando il client tenta di connettersi”), è molto improbabile. Non l’ho incluso originariamente perché l’avevo escluso mentalmente prima di rispondere.

Ho ricevuto questo errore quando ho chiamato un servizio web. Il problema era anche legato alla sicurezza del livello di trasporto. Potrei chiamare il servizio web attraverso un progetto di sito web, ma quando riutilizzando lo stesso codice in un progetto di test otterrei una WebException che conteneva questo messaggio. Aggiungere la 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 Secure Sockets Layer (SSL) o Transport Layer Security (TLS) da utilizzare per le nuove connessioni che utilizzano solo lo schema HTTPS (Secure Hypertext Transfer Protocol); le connessioni esistenti non sono cambiate.

Credo che la configurazione SecurityProtocol sia importante durante l’handshake TLS quando si seleziona la versione del protocollo.

Stringa di mano TLS : questo protocollo viene utilizzato per scambiare tutte le informazioni richieste da entrambe le parti per lo scambio dei dati dell’applicazione effettivi da parte di TLS.

ClientHello : un client invia un messaggio ClientHello che specifica la versione del protocollo TLS più elevata che supporta …

ServerHello : il server risponde con un messaggio ServerHello, contenente la versione del protocollo prescelto … La versione del protocollo scelta deve essere la più alta ansible sia per il client che per il 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.

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

Non so se questo è il default da ora in poi, ma cambiandolo di nuovo a 1.0 ha funzionato.

È ansible accedere alle impostazioni all’interno di “Impostazioni SSL”.

Anche le chiamate ai servizi HTTPS da uno dei nostri server lanciavano l’eccezione ” Imansible leggere i dati dalla connessione di trasporto: una connessione esistente è stata chiusa forzatamente “. Il servizio HTTP, tuttavia, ha funzionato bene. Usato Wireshark per vedere che si trattava di un errore di handshake TLS. Alla fine è stato necessario aggiornare la suite di crittografia sul server.

Per qualche motivo, la connessione al server è stata persa. Potrebbe essere che il server abbia chiuso esplicitamente la connessione, o che un bug sul server abbia causato la sua 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 mettere un po ‘di debug lì per dirti quando le connessioni client sono chiuse. Questo potrebbe darti qualche indicazione su quando e perché le connessioni vengono eliminate.

Sul client, è necessario scrivere il codice per tenere conto della possibilità che il server non funzioni in qualsiasi momento. È proprio così: le connessioni di rete sono intrinsecamente inaffidabili.

Ciò non sarà di aiuto per problemi intermittenti, ma potrebbe essere utile per altre persone con problemi simili.

Avevo clonato una VM e l’ho avviato su una rete diversa con un nuovo indirizzo IP, ma non ho cambiato i binding in IIS. Fiddler mi stava mostrando “Imansible leggere i dati dalla connessione di trasporto: una connessione esistente è stata forzatamente chiusa dall’host remoto” e IE mi ha detto “Attiva TLS 1.0, TLS 1.1 e TLS 1.2 in Impostazioni avanzate”. Cambiare l’associazione al nuovo indirizzo IP l’ha risolto per me.

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, ho inserito 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 so, correggimi se sbaglio. Ma secondo la mia ricerca, non è un problema di codice – è stato in realtà dalla macchina stessa.

Felice codifica!

Avevo un’applicazione di terzi (Fiddler) in esecuzione per provare a vedere le richieste inviate. La chiusura di questa applicazione lo ha risolto per me

Questo ha risolto il mio problema. Ho aggiunto questa riga prima che venga fatta la richiesta:

 System.Net.ServicePointManager.Expect100Continue = false; 

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

 System.Net.ServicePointManager.Expect100Continue = false; 

A volte questo problema si verifica a causa del server proxy implementato sul server web. Per ignorare il server proxy mettendo questa linea prima di chiamare il servizio di invio.

Abbiamo riscontrato un problema molto simile in cui il sito Web di un cliente stava tentando di connettersi al nostro servizio API Web e ottenere lo stesso messaggio. Ciò è iniziato completamente inaspettatamente quando non sono state apportate modifiche al codice o aggiornamenti di Windows sul server su cui IIS era in esecuzione.

Nel nostro caso si è scoperto che il sito Web di chiamata utilizzava una versione di .Net che supportava solo TLS 1.0 e per qualche motivo il server su cui era in esecuzione IIS interrotto sembrava aver smesso di accettare le 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 reg:

 [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 ad 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 far sì che il sito Web del cliente aggiornasse il proprio codice per utilizzare TLS 1.2, ma le voci del registro di cui sopra possono aiutare a diagnosticare il problema in primo luogo.