Tidak dapat membaca data dari koneksi transportasi: Koneksi yang ada ditutup secara paksa oleh host jarak jauh

103

Saya memiliki aplikasi server dan terkadang, ketika klien mencoba untuk terhubung, saya mendapatkan kesalahan berikut:

masukkan deskripsi gambar di sini

CATATAN: "tidak bisa mendapatkan streaming dari klien atau login gagal" adalah teks yang ditambahkan oleh saya dalam pernyataan catch

dan garis di mana ia berhenti (sThread: line 96) adalah:

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

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

Apa yang mungkin menyebabkan masalah ini? Perhatikan bahwa itu tidak terjadi setiap saat

Alex
sumber

Jawaban:

63

Kesalahan ini biasanya berarti bahwa mesin target sedang berjalan, tetapi layanan yang Anda coba sambungkan tidak tersedia. (Entah itu berhenti, macet, atau sibuk dengan permintaan lain.)

Dalam bahasa Inggris: Koneksi ke mesin (host / server / PC jarak jauh tempat layanan dijalankan) dibuat tetapi karena layanan tidak tersedia pada mesin itu, mesin tidak tahu apa yang harus dilakukan dengan permintaan tersebut.

Jika koneksi ke mesin tidak tersedia, Anda akan melihat kesalahan yang berbeda. Saya lupa apa itu, tapi di sepanjang baris "Service Unreachable" atau "Unavailable".

Edit - ditambahkan

Ada kemungkinan bahwa hal ini disebabkan oleh firewall yang memblokir port, tetapi mengingat Anda mengatakan itu terputus-putus ("terkadang ketika klien mencoba untuk menyambung"), itu sangat tidak mungkin. Saya tidak memasukkan itu awalnya karena saya telah mengesampingkannya secara mental sebelum menjawab.

David
sumber
1
masalahnya adalah bahwa ketika saya memulai server, ada sekitar 50 klien yang terhubung ke server saya. Saya telah menerapkan semacam sinyal tunggu ketika menerima klien .. seperti while (Program.waitToFinishLoginAtClient == true && ajutor <30) {Thread.Sleep (300); ajutor ++; } klien = this.tcpListener.AcceptTcpClient (); Program.waitToFinishLoginAtClient = true; ........... dan Program.waitToFinishAtClient diubah di utas yang berisi klien
Alex
mungkinkah "menunggu" ini menjadi masalah?
Alex
1
haruskah saya membiarkannya saja? tidak menunggu?
Alex
1
Saya pikir Menunggu adalah masalahnya. Saya tidak cukup tahu tentang kode Anda untuk memastikannya, tapi itu terdengar mungkin. Hanya ingin tahu, apakah Anda membangun layanan Anda sendiri dengan "cara yang sulit" atau jika Anda menggunakan WCF atau bahkan Remoting untuk ini ...
David
Berdasarkan kode kecil di sini, menurut saya masalah "tunggu" dapat dihindari jika berada di dalam utas terpisah untuk setiap sambungan. Untuk berjaga-jaga jika tebakannya benar, berikut adalah contoh Layanan TCP multi-threaded dengan multi-threading yang dapat membantu Anda: switchonthecode.com/tutorials/…
David
180

Saya menerima kesalahan ini saat memanggil layanan web. Masalah tersebut juga terkait dengan keamanan tingkat transportasi. Saya dapat memanggil layanan web melalui proyek situs web, tetapi ketika menggunakan kembali kode yang sama dalam proyek uji saya akan mendapatkan WebException yang berisi pesan ini. Menambahkan baris berikut sebelum melakukan panggilan menyelesaikan masalah:

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

Edit

System.Net.ServicePointManager.SecurityProtocol - Properti ini memilih versi protokol Secure Sockets Layer (SSL) atau Transport Layer Security (TLS) yang akan digunakan untuk sambungan baru yang menggunakan skema Secure Hypertext Transfer Protocol (HTTPS) saja; koneksi yang ada tidak berubah.

Saya yakin SecurityProtocolkonfigurasi ini penting selama jabat tangan TLS saat memilih versi protokol.

Jabat tangan TLS - Protokol ini digunakan untuk menukar semua informasi yang dibutuhkan oleh kedua belah pihak untuk pertukaran data aplikasi aktual oleh TLS.

ClientHello - Klien mengirim pesan ClientHello yang menetapkan versi protokol TLS tertinggi yang didukungnya ...

ServerHello - Server merespons dengan pesan ServerHello, berisi versi protokol yang dipilih ... Versi protokol yang dipilih harus yang tertinggi yang didukung oleh klien dan server. Misalnya, jika klien mendukung TLS versi 1.1 dan server mendukung versi 1.2, versi 1.1 harus dipilih; versi 1.2 tidak boleh dipilih.

Hans Vonn
sumber
8
ini menyelamatkan saya! Terima kasih sobat. di debugger saya, saya mencoba memanggil layanan https saat menguji dan mengalami masalah yang dialami OP.
Blair Holmes
6
Apakah kita tahu lebih banyak tentang bagaimana / mengapa ini berhasil? Saya telah berjuang dengan panggilan PostAsync dan ini tampaknya memperbaiki kesalahan saya juga. Senang berhasil, tapi saya juga ingin tahu alasannya.
Kevin Matlock
1
@HansVonn Terima kasih untuk ini! Menyelamatkan saya banyak waktu - Mengenai mengapa ini berfungsi Itu hanya membatasi versi TLS yang Anda gunakan saat Anda terhubung.
bingung dan
1
Tidak percaya ini membuat saya sekali lagi! Terima kasih
Sergio A.
2
TERIMA KASIH! Ini membuatku gila.
mknopf
34

Skenario kasus khusus saya adalah bahwa layanan aplikasi Azure memiliki versi TLS minimum yang diubah menjadi 1.2

Saya tidak tahu apakah itu default mulai sekarang, tetapi mengubahnya kembali ke 1.0 membuatnya berfungsi.

Anda dapat mengakses pengaturan di dalam "Pengaturan SSL".

Hugo Hilário
sumber
7
Oh my god TERIMA KASIH BANYAK! Saya sudah terjebak dalam hal ini untuk waktu yang lama, dan saya memeriksa pengaturan SSL dari aplikasi web, dan minimum ditetapkan ke 1.2, bukan 1.0. Ketika saya mengubahnya kembali ke 1.0 dan memulai ulang aplikasi web, itu berhasil! Terima kasih banyak!
Mason
1
Terima kasih banyak, @ hugo-hilário, luar biasa berhasil juga untuk saya! Bagaimana Anda bisa menemukan solusi yang begitu rumit! : D
hosjay
@hosjay itu adalah neraka bagi saya juga :)
Hugo Hilário
3
Menyelamatkan teman hari saya!
Nitesh
Saya mengalami masalah ini untuk Azure Function v2
Pieter Heemeryck
17

Tidak yakin perbaikan mana di postingan blog ini yang membantu, tetapi salah satu dari mereka menyelesaikan masalah ini untuk saya ...

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

Trik yang membantu saya adalah berhenti menggunakan WebRequest dan menggunakan HttpWebRequest sebagai gantinya. HttpWebRequest memungkinkan saya untuk bermain dengan 3 pengaturan penting:

dan

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

  • LANGKAH 1: Nonaktifkan KeepAlive
  • LANGKAH 2: Setel ProtocolVersion ke Version10
  • LANGKAH 3: Membatasi jumlah titik layanan
SteveC
sumber
1
Jawaban inilah yang memecahkan masalah yang sama bagi saya. Saya mematikan 'Keep Alive' di bagian Http Response Headers di IIS7
drzounds
Saya harus menambahkan bahwa saya juga harus menambahkan kode ini ke Reference.cs untuk layanan web yang mengalami perilaku itu. dilindungi override System.Net.WebRequest GetWebRequest (Uri uri) {System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest) base.GetWebRequest (uri); webRequest.KeepAlive = false; kembali webRequest; }
drzounds
11

Panggilan ke layanan HTTPS dari salah satu server kami juga memunculkan pengecualian " Tidak dapat membaca data dari koneksi transport: Koneksi yang ada ditutup secara paksa ". Layanan HTTP, bagaimanapun, bekerja dengan baik. Menggunakan Wireshark untuk melihat bahwa itu adalah Kegagalan jabat tangan TLS. Akhirnya cipher suite di server perlu diperbarui.

Jobrocol
sumber
Inilah yang terjadi dengan saya. A mengirim sertifikat kadaluarsa ke koneksi SSL. A memperbaharui sertifikat dan bekerja.
Guilherme de Jesus Santos
8

Menurut balasan "Hans Vonn".

Menambahkan baris berikut sebelum melakukan panggilan menyelesaikan masalah:

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

Setelah menambahkan protokol Keamanan dan berfungsi dengan baik tetapi saya harus menambahkan sebelum setiap panggilan API yang tidak sehat. Saya baru saja memutakhirkan .net framework versi setidaknya 4.6 dan bekerja seperti yang diharapkan tidak perlu menambahkan sebelum setiap panggilan API.

Mahi Uddin
sumber
1
Terima kasih banyak. kamu membuat hariku. Mungkin berguna bagi sebagian orang jika saya menyebutkan bahwa sebelum ini saya juga menguji menonaktifkan firewall dan menambahkan ServicePointManager.ServerCertificateValidationCallback tetapi tidak berfungsi.
Tekin
5

Ini tidak akan membantu untuk masalah sesekali, tetapi mungkin berguna untuk orang lain dengan masalah serupa.

Saya telah mengkloning VM dan memulainya di jaringan lain dengan alamat IP baru tetapi tidak mengubah binding di IIS. Fiddler menunjukkan kepada saya "Tidak dapat membaca data dari koneksi transportasi: Koneksi yang ada ditutup secara paksa oleh host jarak jauh" dan IE memberi tahu saya "Aktifkan TLS 1.0, TLS 1.1, dan TLS 1.2 dalam pengaturan Lanjutan". Mengubah pengikatan ke alamat IP baru menyelesaikannya untuk saya.

Jon.Mozley
sumber
2

Untuk beberapa alasan, koneksi ke server terputus. Bisa jadi server secara eksplisit menutup koneksi, atau bug pada server menyebabkannya ditutup secara tidak terduga. Atau sesuatu antara klien dan server (sakelar atau router) memutuskan koneksi.

Mungkin kode server yang menyebabkan masalah, dan mungkin tidak. Jika Anda memiliki akses ke kode server, Anda dapat meletakkan beberapa debugging di sana untuk memberi tahu Anda ketika koneksi klien ditutup. Itu mungkin memberi Anda beberapa indikasi tentang kapan dan mengapa koneksi diputus.

Pada klien, Anda harus menulis kode Anda untuk memperhitungkan kemungkinan server gagal kapan saja. Begitulah adanya: koneksi jaringan pada dasarnya tidak dapat diandalkan.

Jim Mischel
sumber
2

Ini memecahkan masalah saya. Saya menambahkan baris ini sebelum permintaan dibuat:

System.Net.ServicePointManager.Expect100Continue = false;

Tampaknya ada proxy di jalan server yang tidak mendukung perilaku 100-lanjutkan.

Mahdi Ataollahi
sumber
1

Saya mendapatkan masalah itu di masa lalu. Saya menggunakan PostgreSQL dan ketika saya menjalankan program saya, terkadang program terhubung dan terkadang muncul kesalahan seperti itu.

Ketika saya bereksperimen dengan kode saya, saya meletakkan kode Koneksi saya di baris pertama di bawah Formulir publik. Berikut ini contohnya:

SEBELUM:

    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());
        }

SEKARANG:

    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!

        }

Saya kira programnya harus membaca dulu koneksinya sebelum melakukan apa-apa, entahlah, perbaiki saya jika saya salah. Tetapi menurut penelitian saya, ini bukan masalah kode - ini sebenarnya dari mesin itu sendiri.

Selamat Coding!

Coder pinggir jalan
sumber
1
System.Net.ServicePointManager.Expect100Continue = false;

Masalah ini terkadang terjadi karena alasan server proxy diterapkan pada server web. Untuk melewati server proxy dengan meletakkan baris ini sebelum memanggil layanan pengiriman.

Tahir Alvi
sumber
0

Saya menjalankan aplikasi Pihak Ketiga (Fiddler) untuk mencoba dan melihat permintaan yang dikirim. Menutup aplikasi ini memperbaikinya untuk saya

Johan Aspeling
sumber
0

Kami mengalami masalah yang sangat mirip ketika situs web klien mencoba menyambung ke layanan API Web kami dan mendapatkan pesan yang sama. Ini mulai terjadi secara tiba-tiba ketika tidak ada perubahan kode atau pembaruan Windows di server tempat IIS berjalan.

Dalam kasus kami, ternyata situs web pemanggil menggunakan versi .Net yang hanya mendukung TLS 1.0 dan untuk beberapa alasan server tempat IIS kami berjalan berhenti tampaknya telah berhenti menerima panggilan TLS 1.0. Untuk mendiagnosis bahwa kami harus mengaktifkan TLS secara eksplisit melalui registri di server IIS dan kemudian memulai ulang server tersebut. Ini adalah kunci 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

Jawaban saya untuk pertanyaan lain di sini memiliki skrip PowerShell yang kami gunakan untuk menambahkan entri:

CATATAN: Mengaktifkan protokol keamanan lama bukanlah ide yang baik, jawaban yang benar dalam kasus kami adalah meminta situs web klien memperbarui kodenya untuk menggunakan TLS 1.2, tetapi entri registri di atas dapat membantu mendiagnosis masalah di tempat pertama.

tomRedox
sumber
0

Alasan hal ini terjadi pada saya adalah karena saya memiliki ketergantungan rekursif pada penyedia DI saya. Dalam kasus saya, saya memiliki:

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

Perbaiki adalah hanya menghapus pendaftaran layanan cakupan kedua

services.AddScoped(provider => new CfDbContext(builder.Options));
Madison Haynie
sumber
0

Jika Anda memiliki sertifikat https pada domain, pastikan Anda memiliki https yang mengikat nama domain di IIS. Di IIS -> Pilih domain Anda -> Klik pada Bindings Site Bindings Window terbuka. Tambahkan pengikatan untuk https.

pengguna2147447
sumber
0

Memiliki masalah serupa dan mendapatkan kesalahan berikut tergantung pada aplikasi apa yang saya gunakan dan apakah kami melewati firewall / load balancer atau tidak:

Jabat tangan HTTPS ke [bla] (untuk # 136) gagal. System.IO.IOException Tidak dapat membaca data dari koneksi transport: Koneksi yang ada ditutup secara paksa oleh remote host

dan

ReadResponse () gagal: Server tidak mengembalikan respons lengkap untuk permintaan ini. Server mengembalikan 0 byte.

Masalahnya ternyata Sertifikat Server SSL tidak terjawab dan tidak diinstal di beberapa server.

anjing mematikan
sumber
0

Coba periksa apakah Anda dapat menjalin jabat tangan sejak awal. Saya mengalami masalah ini sebelumnya ketika mengunggah file dan saya hanya menemukan bahwa masalahnya adalah rute yang tidak ada ketika saya menghapus unggahan dan memeriksa apakah itu dapat masuk dengan parameter.

Raffy
sumber
0

Bagi saya, itu adalah masalah di mana di IIS mengikat itu memiliki alamat IP dari server web. Saya mengubahnya untuk menggunakan semua IP yang tidak ditetapkan dan aplikasi saya mulai berfungsi.

Shivaram Gopalakrishnan
sumber
0

Saya mengalami kesalahan dengan python clr menjalankan kueri mdx ke layanan analitik Microsoft menggunakan adomd

Saya menyelesaikannya dengan bantuan Hans Vonn dan ini versi python :

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

Bagi mereka yang mungkin menemukan ini nanti, setelah .NET versi 4.6, saya mengalami masalah ini juga.

Pastikan Anda memeriksa file web.config Anda untuk baris berikut:

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

Jika Anda menjalankan 4.6.x atau versi .NET yang lebih tinggi di server, pastikan Anda menyesuaikan nilai targetFramework ini agar sesuai dengan versi kerangka kerja di server Anda. Jika versi Anda membaca kurang dari 4.6.x, maka saya akan merekomendasikan Anda memutakhirkan .NET dan menggunakan versi yang lebih baru kecuali kode Anda bergantung pada versi yang lebih lama (yang, dalam hal ini, Anda harus mempertimbangkan untuk memperbaruinya).

Saya mengubah targetFrameworks menjadi 4.7.2 dan masalah menghilang:

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

Kerangka kerja yang lebih baru menyelesaikan masalah ini dengan menggunakan protokol terbaik yang tersedia dan memblokir yang tidak aman atau usang. Jika layanan jarak jauh yang Anda coba sambungkan atau panggil memberikan kesalahan ini, bisa jadi mereka tidak mendukung protokol lama lagi.

Zachary Weber
sumber