SmtpException: Tidak dapat membaca data dari koneksi transport: net_io_connectionclosed


103

Saya menggunakan SmtpClientperpustakaan untuk mengirim email menggunakan berikut ini:

SmtpClient client = new SmtpClient();
client.Host = "hostname";
client.Port = 465;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.EnableSsl = true;
client.Credentials = new NetworkCredential("User", "Pass);
client.Send("from@hostname", "to@hostname", "Subject", "Body");

Kode berfungsi dengan baik di lingkungan pengujian saya, tetapi ketika saya menggunakan server SMTP produksi, kode gagal dengan SmtpException"Kegagalan pengiriman email." dengan bagian dalam IOException"Tidak dapat membaca data dari koneksi transport: net_io_connectionclosed".

Saya telah mengonfirmasi bahwa firewall tidak menjadi masalah. Port terbuka dengan baik antara klien dan server. Saya tidak yakin apa lagi yang bisa menyebabkan kesalahan ini.

Jawaban:


190

EDIT: Versi Super Redux

Coba port 587, bukan 465. Port 465 secara teknis sudah usang.


Setelah sekumpulan paket mengendus, saya menemukan jawabannya. Pertama, inilah jawaban singkatnya:

.NET SmtpClient hanya mendukung enkripsi melalui STARTTLS. Jika EnableSslbendera disetel, server harus menanggapi EHLO dengan STARTTLS, jika tidak maka akan memunculkan pengecualian. Lihat dokumentasi MSDN untuk lebih jelasnya.

Kedua, pelajaran sejarah SMTP singkat bagi mereka yang tersandung masalah ini di masa depan:

Dulu, ketika layanan ingin juga menawarkan enkripsi, mereka diberi nomor port yang berbeda, dan pada nomor port itu mereka segera memulai koneksi SSL. Seiring berjalannya waktu, mereka menyadari bahwa membuang dua nomor port untuk satu layanan adalah konyol dan mereka menemukan cara untuk layanan yang memungkinkan teks biasa dan enkripsi pada port yang sama menggunakan STARTTLS. Komunikasi akan mulai menggunakan teks biasa, lalu gunakan perintah STARTTLS untuk meningkatkan ke koneksi terenkripsi. STARTTLS menjadi standar untuk enkripsi SMTP. Sayangnya, seperti yang selalu terjadi ketika standar baru diterapkan, ada kompatibilitas campur aduk dengan semua klien dan server di luar sana.

Dalam kasus saya, pengguna saya mencoba menyambungkan perangkat lunak ke server yang memaksa sambungan SSL langsung, yang merupakan metode lawas yang tidak didukung oleh Microsoft di .NET.


bagaimana cara mengetahui apakah Server yang saya sambungkan memiliki masalah yang sama? Saya mencoba menggunakan SmtpClient dengan yahoo dan / atau gmail dan mendapatkan kesalahan yang dijelaskan. Ketika saya mencoba melawan server pertukaran 2013, kode saya berfungsi dengan baik.
raider33

11
Cara paling sederhana untuk menguji adalah dengan mencoba menggunakan port 587 dan bukan 465. Meskipun beberapa server SMTP mendukung TLS pada 465 (dan terkadang bahkan 25), hanya port 587 yang diperlukan untuk mendukung TLS. Selain itu, penggunaan port 465 sudah tidak digunakan lagi sejak 1998 ( en.wikipedia.org/wiki/SMTPS ), meskipun dalam praktiknya banyak server yang mengaktifkannya untuk klien lama.
Jake C

1
Ya, mengubah ke 587 berhasil. Terima kasih telah mengarahkan saya ke arah yang benar.
raider33

2
587 berfungsi meskipun smtp.att.yahaoo.com mengatakan gunakan 465. Thanks man.
Sam

1
Untuk solusi sebenarnya, lihat stackoverflow.com/a/1014876/247702 tentang penggunaan System.Web.Mail (tidak digunakan lagi) yang mendukung SSL implisit.
pengguna247702

20

Ubah port dari 465 menjadi 587 dan itu akan berfungsi.


3
Saya tidak yakin apa yang terjadi tetapi ini berhasil saya menggunakan gmail smtp. dapatkah Anda menjelaskan mengapa ini berhasil?
Krismogram

20

Bagi siapa saja yang menemukan posting ini mencari solusi dan Anda telah menyiapkan sendgrid SMTP melalui Azure.

Nama pengguna bukanlah nama pengguna yang Anda siapkan ketika Anda telah membuat objek sendgrid dengan warna azure. Untuk menemukan nama pengguna Anda;

  • Klik pada objek sendgrid Anda dalam warna biru dan klik kelola. Anda akan diarahkan ke situs SendGrid.
  • Konfirmasikan email Anda dan salin nama pengguna yang ditampilkan di sana .. itu adalah nama pengguna yang dibuat secara otomatis.
  • Tambahkan nama pengguna dari SendGrid ke dalam pengaturan SMTP Anda di file web.config.

Semoga ini membantu!


2
Ini mungkin tampak konyol tetapi hal lain yang mungkin ingin Anda periksa adalah apakah kata sandi sudah benar untuk penyiapan SMTP SendGrid. Pengaturan kami awalnya berfungsi dan kemudian suatu hari kami mulai mendapatkan pesan pengecualian OP. Pencarian di WWW sebagian besar menunjuk pada melihat konfigurasi Server SMTP lainnya ketika akhirnya ternyata kata sandinya salah. Seseorang dalam tim telah mengubah kata sandi di file konfigurasi ke variasi di mana huruf pertama tidak menggunakan huruf besar.
methon.dagger

1
Dalam kasus saya, nama pengguna salah dan salah ketik. Tetapi kata sandi yang salah juga dapat menyebabkan pesan "Tidak dapat membaca data dari koneksi transport: net_io_connectionclosed." kesalahan. Jadi, periksa nama pengguna dan kata sandi. Dan untuk pengguna Azure, nama pengguna dalam format "azure_guid-withoutdashes@azure.com" (misalnya: azure_e9e062db4bfd491296bec77bcff49ed9@azure.com)
Raj Rao

10

Anda mungkin juga harus mengubah setelan "aplikasi kurang aman" di akun Gmail Anda. EnableSsl, gunakan port 587 dan aktifkan "aplikasi kurang aman". Jika Anda mencari di google bagian aplikasi yang kurang aman, ada halaman bantuan google yang akan menautkan Anda langsung ke halaman akun Anda. Itu adalah masalah saya tetapi semuanya berfungsi sekarang berkat semua jawaban di atas.


Terima kasih Bill. Ini masih berfungsi dengan akun gmail standar saya. Jika Anda tidak menggunakan setelan "aplikasi kurang aman", Anda harus menggunakan autentikasi 2 bagian OAuth2. Ini tidak praktis bila Anda hanya ingin mengirim email konfirmasi dari situs web.
Dan Randolph

1
Di mana pengaturan "aplikasi kurang aman". Saya di akun gmail saya mencarinya.
Sam

1
Saya menemukan setelan "Aplikasi yang Kurang Aman" - bukan di Setelan Gmail, tetapi di Setelan Akun Google: Akun Saya> Masuk dan Keamanan myaccount.google.com/…
HFloyd

9

Saya sudah mencoba semua jawaban di atas tetapi masih mendapatkan kesalahan ini dengan akun Office 365. Kode tersebut tampaknya berfungsi dengan baik dengan akun Google dan smtp.gmail.com saat mengizinkan aplikasi yang kurang aman.

Ada saran lain yang bisa saya coba?

Ini kode yang saya gunakan

int port = 587;
string host = "smtp.office365.com";
string username = "smtp.out@mail.com";
string password = "password";
string mailFrom = "noreply@mail.com";
string mailTo = "to@mail.com";
string mailTitle = "Testtitle";
string mailMessage = "Testmessage";

using (SmtpClient client = new SmtpClient())
{
    MailAddress from = new MailAddress(mailFrom);
    MailMessage message = new MailMessage
    {
        From = from
    };
    message.To.Add(mailTo);
    message.Subject = mailTitle;
    message.Body = mailMessage;
    message.IsBodyHtml = true;
    client.DeliveryMethod = SmtpDeliveryMethod.Network;
    client.UseDefaultCredentials = false;
    client.Host = host;
    client.Port = port;
    client.EnableSsl = true;
    client.Credentials = new NetworkCredential
    {
        UserName = username,
        Password = password
    }; 
    client.Send(message);
}

PERBARUI DAN BAGAIMANA SAYA MENYELESAIKANNYA:

Mengatasi masalah dengan mengubah Klien Smtp ke Mailkit. Klien Smtp System.Net.Mail sekarang tidak disarankan untuk digunakan oleh Microsoft karena masalah keamanan dan Anda seharusnya menggunakan MailKit. Menggunakan Mailkit memberi saya pesan kesalahan yang lebih jelas sehingga saya dapat memahami menemukan akar penyebab masalah (masalah lisensi). Anda bisa mendapatkan Mailkit dengan mendownloadnya sebagai Paket Nuget .

Baca dokumentasi tentang Klien Smtp untuk informasi lebih lanjut: https://docs.microsoft.com/es-es/dotnet/api/system.net.mail.smtpclient?redirectedfrom=MSDN&view=netframework-4.7.2

Berikut adalah cara saya mengimplementasikan SmtpClient dengan MailKit

        int port = 587;
        string host = "smtp.office365.com";
        string username = "smtp.out@mail.com";
        string password = "password";
        string mailFrom = "noreply@mail.com";
        string mailTo = "mailto@mail.com";
        string mailTitle = "Testtitle";
        string mailMessage = "Testmessage";

        var message = new MimeMessage();
        message.From.Add(new MailboxAddress(mailFrom));
        message.To.Add(new MailboxAddress(mailTo));
        message.Subject = mailTitle;
        message.Body = new TextPart("plain") { Text = mailMessage };

        using (var client = new SmtpClient())
        {
            client.Connect(host , port, SecureSocketOptions.StartTls);
            client.Authenticate(username, password);

            client.Send(message);
            client.Disconnect(true);
        }

3

Apakah perpustakaan SMTP Anda mendukung koneksi terenkripsi? Server email mungkin mengharapkan koneksi TLS yang aman dan karenanya menutup koneksi jika tidak ada handshake TLS


Ini hanya SmtpClientpustaka .NET default , itu mendukung encrytpion, server memang memerlukan enkripsi, dan saya telah mengaturnya client.EnableSssl = true;. Meskipun saya pikir saya akan melanjutkan ini sedikit lebih jauh dengan Wireshark.
Jake C

3

Jika Anda menggunakan server SMTP pada kotak yang sama dan SMTP Anda terikat ke alamat IP, bukan "Any Assigned", ini mungkin gagal karena mencoba menggunakan alamat IP (seperti 127.0.0.1) yang saat ini tidak berfungsi SMTP di.


2

Untuk meningkatkan apa yang disebut jocull dalam komentar, saya melakukan semua yang disebutkan di utas ini dan menyerang ... karena milik saya berada dalam satu lingkaran untuk dilindas berulang-ulang; setelah pertama kali melalui loop, terkadang gagal. Selalu bekerja pertama kali melalui loop.

Untuk memperjelas: loop menyertakan pembuatan SmtpClient, dan kemudian melakukan .Send dengan data yang benar. SmtpClient dibuat di dalam blok coba / tangkap, untuk menangkap kesalahan dan untuk memastikan objek dihancurkan sebelum bagian bawah loop.

Dalam kasus saya, solusinya adalah memastikan bahwa SmtpClient dibuang setelah setiap kali dalam loop (baik melalui menggunakan () pernyataan atau dengan melakukan pembuangan manual). Bahkan jika objek SmtpClient secara implisit dihancurkan dalam loop, .NET tampaknya membiarkan hal-hal yang ada di sekitar untuk konflik dengan upaya berikutnya.



2

menghapus

client.UseDefaultCredentials = false; 

sepertinya menyelesaikannya untuk saya.


1

Dalam kasus saya, pelanggan lupa menambahkan alamat IP baru di pengaturan SMTP mereka. Buka IIS 6.0 di server yang menyiapkan smtp, klik kanan server virtual Smtp, pilih Properties, tab Access, klik Connections, tambahkan alamat IP dari server baru. Kemudian klik Relay, tambahkan juga alamat IP server baru. Ini memecahkan masalah saya.


0

Coba ini: Berikut adalah kode yang saya gunakan untuk mengirim email ke banyak pengguna.

 public string gmail_send()
    {
        using (MailMessage mailMessage =
        new MailMessage(new MailAddress(toemail),
    new MailAddress(toemail)))
        {
            mailMessage.Body = body;
            mailMessage.Subject = subject;
            try
            {
                SmtpClient SmtpServer = new SmtpClient();
                SmtpServer.Credentials =
                    new System.Net.NetworkCredential(email, password);
                SmtpServer.Port = 587;
                SmtpServer.Host = "smtp.gmail.com";
                SmtpServer.EnableSsl = true;
                mail = new MailMessage();
                String[] addr = toemail.Split(','); // toemail is a string which contains many email address separated by comma
                mail.From = new MailAddress(email);
                Byte i;
                for (i = 0; i < addr.Length; i++)
                    mail.To.Add(addr[i]);
                mail.Subject = subject;
                mail.Body = body;
                mail.IsBodyHtml = true;
                mail.DeliveryNotificationOptions =
                    DeliveryNotificationOptions.OnFailure;
                //   mail.ReplyTo = new MailAddress(toemail);
                mail.ReplyToList.Add(toemail);
                SmtpServer.Send(mail);
                return "Mail Sent";
            }
            catch (Exception ex)
            {
                string exp = ex.ToString();
                return "Mail Not Sent ... and ther error is " + exp;
            }
        }
    }

1
SmtpClientjuga Disposable, jadi harus dibungkus dengan usingblok
jocull

0

Jika semua solusi di atas tidak berfungsi untuk Anda, coba perbarui file berikut ke server Anda (dengan mempublikasikan maksud saya, dan build sebelumnya akan membantu).

bin-> projectname.dll 

Setelah memperbarui Anda akan melihat kesalahan ini. karena saya telah menyelesaikannya dengan solusi ini.


1
Hebatnya, ini berhasil untuk saya! Izinkan aplikasi tidak aman aktif dan port sudah disetel ke 587.
TechyGypo

Terima kasih, baru menyadari bahwa saya bukan satu-satunya yang mengalami masalah ini. Saya senang bisa membantu.
Ajay Kumar

0

Untuk Outlook, gunakan pengaturan berikut yang tidak memberikan kesalahan kepada saya

Nama server SMTP smtp-mail.outlook.com

Port SMTP 587


0

Kesalahan ini sangat umum. Hal ini dapat disebabkan oleh berbagai alasan seperti server email salah. Beberapa perusahaan hosting menggunakan format mail.domainname. Jika Anda hanya menggunakan nama domain itu tidak akan berhasil. periksa kredensial nama host kata sandi nama pengguna jika perlu Periksa dengan perusahaan hosting.

<smtp from="info@india.uu.com">
        <!-- Uncomment to specify SMTP settings -->
        <network host="domain.com" port="25" password="Jin@" userName="info@india.xx.com"/>
      </smtp>
    </mailSettings>

0

Dalam kasus saya, IP server web diblokir di server email, itu perlu dibatalkan pemblokirannya oleh perusahaan hosting Anda dan membuatnya masuk daftar putih. Selain itu, gunakan porta 587.


0

Jika server email Anda adalah Gmail (smtp.google.com), Anda akan mendapatkan kesalahan ini ketika Anda mencapai batas pesan. Gmail mengizinkan pengiriman melalui SMTP hingga hanya 2000 pesan per 24 jam.


0

Saya mengalami ini saat menggunakan smtp.office365.com, menggunakan port 587 dengan SSL. Saya dapat masuk ke akun menggunakan portal.office.com dan saya dapat mengonfirmasi bahwa akun tersebut memiliki lisensi. Tetapi ketika saya mengaktifkan kode untuk mengirim email, saya terus mendapatkan kesalahan net_io_connectionclosed.

Butuh beberapa waktu untuk mengetahuinya, tetapi admin Exchange menemukan pelakunya. Kami menggunakan O365 tetapi server Exchange berada dalam lingkungan hybrid. Meskipun akun yang kami coba gunakan telah disinkronkan ke Azure AD dan memiliki lisensi O365 yang valid, untuk beberapa alasan kotak surat masih berada di server Exchange hibrid - bukan Exchange online. Setelah pertukaran admin menggunakan perintah "Pindahkan-Kotak Surat" untuk memindahkan kotak surat dari server pertukaran hibrid ke O365, kita dapat menggunakan kode tersebut untuk mengirim email menggunakan o365.


-1

Siapkan: 1. HostA adalah server virtual SMTP dengan port default 25 2. HostB adalah workstation tempat saya mengirim email dengan SmtpClient dan mensimulasikan jaringan tidak stabil yang saya gunakan kikuk

Kasus 1 Diberikan Jika HostB adalah 2008R2 Ketika saya mengirim email. Kemudian masalah ini terjadi.

Kasus 2 Diberikan Jika HostB adalah 2012 atau versi yang lebih tinggi Ketika saya mengirim email. Kemudian surat itu dikirim.

Kesimpulan: Akar masalah ini terkait dengan Windows Server 2008R2.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.