SmtpException: Не вдається прочитати дані з транспортного з'єднання: net_io_connectionclosed


103

Я використовую SmtpClientбібліотеку для надсилання електронних листів за допомогою наступного:

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");

Код відмінно працює в моєму тестовому середовищі, але коли я використовую виробничі SMTP-сервери, код виходить з ладу з SmtpException"Помилковим відправленням пошти". із внутрішнім IOException"Неможливо прочитати дані з транспортного з'єднання: net_io_connectionclosed".

Я підтвердив, що міжмережеві стіни - це не проблема. Порт відкривається чудово між клієнтом і сервером. Я не впевнений, що ще могло призвести до цієї помилки.

Відповіді:


190

EDIT: Версія Super Redux

Спробуйте порт 587 замість 465. Порт 465 технічно застарів.


Після купки нюхання пакету я зрозумів це. Спочатку ось коротка відповідь:

.NET підтримує шифрування SmtpClient лише через STARTTLS. Якщо EnableSslпрапор встановлений, сервер повинен відповісти на EHLO STARTTLS, інакше він викине виняток. Детальнішу інформацію див. У документації MSDN .

По-друге, швидкий урок історії SMTP для тих, хто натрапить на цю проблему в майбутньому:

Ще в той день, коли служби хотіли також запропонувати шифрування, їм було призначено інший номер порту, і на цей номер порту вони негайно ініціювали з'єднання SSL. З плином часу вони зрозуміли, що нерозумно марнувати два номери портів на одну послугу, і вони розробили спосіб надання послуг, щоб дозволити простий текст і шифрування на одному порту за допомогою STARTTLS. Зв'язок розпочнеться з простого тексту, а потім скористається командою STARTTLS для оновлення до зашифрованого з'єднання. STARTTLS став стандартом для шифрування SMTP. На жаль, як це завжди буває, коли впроваджується новий стандарт, там розташовується сукупність сумісності з усіма клієнтами та серверами.

У моєму випадку мій користувач намагався підключити програмне забезпечення до сервера, який змушував негайне з'єднання SSL, що є застарілим методом, який Microsoft не підтримує в .NET.


як я можу визначити, чи є у Сервера, з яким я з'єднуюся, однакові проблеми? Я намагаюся використовувати SmtpClient з yahoo та / або gmail і отримую описану помилку. Коли я намагаюся проти сервера обміну 2013 року, мій код працює нормально.
raider33

11
Найпростіший спосіб перевірити - спробувати використовувати порт 587, а не 465. Хоча деякі сервери SMTP підтримують TLS на 465 (а іноді навіть на 25), для підтримки TLS потрібен лише порт 587. На додаток до цього використання порту 465 було припинено з 1998 року ( en.wikipedia.org/wiki/SMTPS ), хоча на практиці багато серверів увімкнули його для застарілих клієнтів.
Джейк C

1
Так, зміна на 587 зробила трюк. Дякую, що вказали на мене в правильному напрямку.
raider33

2
587 працює, хоча smtp.att.yahaoo.com каже використання 465. Спасибі людина.
Сем

1
Дійсне рішення див. У розділі stackoverflow.com/a/1014876/247702 щодо використання (застарілої) System.Web.Mail, яка підтримує неявну SSL.
user247702

20

Змініть порт з 465 на 587 і він запрацює.


3
Я не впевнений, що сталося, але це працює для мене за допомогою gmail smtp. Ви можете пояснити, чому це працює?
Крісмограма

20

Для всіх, хто натрапляє на цю посаду, шукаючи рішення, і ви налаштували SMTP sendgrid через Azure.

Ім'я користувача - це не ім’я користувача, яке ви встановили під час створення об’єкта sendgrid в блакитному режимі. Щоб знайти своє ім’я користувача;

  • Клацніть на об'єкт sendgrid в блакитному режимі і натисніть кнопку управління. Ви будете перенаправлені на сайт SendGrid.
  • Підтвердьте свою електронну пошту, а потім скопіюйте вказане ім’я користувача .. це автоматично створене ім’я користувача.
  • Додайте ім’я користувача від SendGrid до налаштувань SMTP у файлі web.config.

Сподіваюся, це допомагає!


2
Це може здатися нерозумним, але щось інше, що ви можете перевірити, - це правильність пароля для установки SMTP SendGrid. Спочатку наша установка працювала, і одного разу ми почали отримувати повідомлення про виняток ОП. Пошуки на WWW здебільшого вказували на перегляд інших конфігурацій сервера SMTP, коли врешті-решт виявилося, що пароль був неправильним. Хтось із команди змінив пароль у файлі конфігурації на зміну, коли перша літера не була написана з великої літери.
methon.dagger

1
У моєму випадку ім'я користувача було невірним та було написано помилково. Але неправильний пароль також може дати "Неможливо прочитати дані з транспортного з'єднання: net_io_connectionclosed". помилка. Тому перевірте і ім’я користувача, і пароль. А для користувачів Azure ім'я користувача має форму "azure_guid-withoutdashes@azure.com" (наприклад: azure_e9e062db4bfd491296bec77bcff49ed9@azure.com)
Raj Rao

10

Можливо, вам також доведеться змінити налаштування "менш безпечних додатків" у своєму акаунті Gmail. ВключітьSsl, використовуйте порт 587 та увімкніть "менш безпечні додатки". Якщо ви перебуваєте в google з менш захищеною частиною додатків, є довідкові сторінки google, які посилають вас прямо на сторінку вашого облікового запису. Це була моя проблема, але все працює зараз завдяки всім відповідям вище.


Дякую Білл. Це все ще працює з моїм стандартним обліковим записом gmail. Якщо ви не використовуєте налаштування "менш безпечних додатків", вам доведеться використовувати автентифікацію OAuth2 з двома частинами. Це не практично, коли ви просто хочете відправити підтвердження електронного листа з веб-сайту.
Ден Рендольф

1
Де розташовуються "менш безпечні додатки". Я в своєму обліковому записі gmail шукаю його.
Сем

1
Я розмістив налаштування "Менш безпечні програми" - це не в налаштуваннях Gmail, а в налаштуваннях акаунта Google: Мій обліковий запис> Вхід та безпека myaccount.google.com/…
HFloyd

9

Я спробував усі відповіді вище, але все ж отримую цю помилку з обліковим записом Office 365. Здається, що код добре працює з обліковим записом Google та smtp.gmail.com, коли надає менш захищені програми.

Будь-які інші пропозиції, які я міг би спробувати?

Ось код, який я використовую

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

ОНОВЛЕННЯ І ЯК Я РОШИЛА

Вирішено проблему шляхом зміни клієнта Smtp на Mailkit. Клієнт System.Net.Mail Smtp тепер не рекомендується використовувати Microsoft через проблеми із безпекою, і замість цього вам слід використовувати MailKit. Використання Mailkit дало мені чіткіші повідомлення про помилки, які я міг зрозуміти, як знайти першопричину проблеми (проблема з ліцензією). Ви можете отримати Mailkit, завантаживши його як Nuget Package.

Прочитайте документацію про клієнта Smtp для отримання додаткової інформації: https://docs.microsoft.com/es-es/dotnet/api/system.net.mail.smtpclient?redirectedfrom=MSDN&view=netframework-4.7.2

Ось як я реалізував SmtpClient з 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

Чи підтримує ваша бібліотека SMTP зашифроване з'єднання? Поштовий сервер, можливо, очікує безпечного TLS-з'єднання і, отже, перерве з'єднання за відсутності рукостискання TLS


Це просто SmtpClientбібліотека .NET , вона підтримує шифрування, сервер вимагає шифрування, і я встановив client.EnableSssl = true;. Хоча я думаю, я збираюся переконати це трохи далі з Wireshark.
Джейк C

3

Якщо ви використовуєте сервер SMTP у тому самому полі, і ваш SMTP прив’язаний до IP-адреси замість "Будь-який призначений", він може вийти з ладу, оскільки він намагається використовувати IP-адресу (наприклад, 127.0.0.1), що SMTP наразі не працює. на.


2

Щоб підняти те, про що йдеться у коментарі, я робив усе, що згадується в цій темі, і викреслював ... тому що моя була в циклі, щоб перебігати знову і знову; після першого разу через цикл, іноді може вийти з ладу. Завжди працював перший раз через петлю.

Щоб було зрозуміло: цикл включає в себе створення SmtpClient, а потім робить .Send з потрібними даними. SmtpClient був створений всередині блоку спробу / лову, щоб виявити помилки та переконатися, що об’єкт знищений перед нижньою ланкою.

У моєму випадку рішення полягало у тому, щоб переконатись, що SmtpClient розміщувався після кожного разу в циклі (або за допомогою оператора (), або шляхом ручного розпорядження). Навіть якщо об'єкт SmtpClient неявно знищується в циклі, .NET, здається, залишає речі, що лежать навколо, щоб суперечити наступній спробі.




1

У випадку, якщо всі вищезазначені рішення не працюють для вас, тоді спробуйте оновити наступний файл на своєму сервері (публікувати я маю на увазі, і збірка до цього була б корисною).

bin-> projectname.dll 

Після оновлення ви побачите цю помилку. як я вирішив цим рішенням.


1
Дивовижно це працювало для мене! Увімкнено незахищені програми, а порт вже встановлено на 587.
TechyGypo

Дякую, щойно зрозумів, що я не єдиний із цим питанням. раді допомогти.
Аджай Кумар

1

У моєму випадку замовник забув додати нову IP-адресу в налаштуваннях SMTP. Відкрийте IIS 6.0 на сервері, який налаштовує smtp, клацніть правою кнопкою миші віртуальний сервер Smtp, виберіть Властивості, вкладку Доступ, виберіть Підключення, додайте IP-адресу нового сервера. Потім натисніть Реле, також додайте IP-адресу нового сервера. Це вирішило моє питання.


0

Спробуйте це: Ось код, який я використовую для надсилання електронної пошти декільком користувачам.

 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
SmtpClientтакож є одноразовим, тому його слід загорнути в usingблок
jocull

0

Для прогнозів використовуйте наступне налаштування, яке не дає мені помилок

Ім'я SMTP-сервера smtp-mail.outlook.com

SMTP-порт 587


0

Ця помилка є дуже загальною. Вона може бути пов’язана з багатьма причинами, такими як поштовий сервер неправильний. Деякі хостинг-компанії використовують формат mail.domainname. Якщо ви просто використовуєте доменне ім’я, це не спрацює. перевірити облікові дані Ім'я хоста ім'я користувача ім'я користувача, якщо потрібно. Зверніться до хостинг-компанії.

<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

У моєму випадку IP-сервер веб-сервера був заблокований на поштовому сервері, його потрібно розблокувати вашою хостинг-компанією та зробити його дозволеним. Також використовуйте порт 587.


0

Якщо ваш поштовий сервер - Gmail (smtp.google.com), ви отримаєте цю помилку, коли натиснете на ліміт повідомлення. Gmail дозволяє надсилати через SMTP до лише 2000 повідомлень за 24 години.


0

Я зіткнувся з цим під час використання smtp.office365.com, використовуючи порт 587 з SSL. Мені вдалося увійти в обліковий запис за допомогою portal.office.com, і я міг підтвердити, що обліковий запис мав ліцензію. Але коли я випустив код для надсилання електронних листів, я продовжував отримувати помилку закритого net_io_connection.

Знадобилося трохи часу, щоб зрозуміти це, але адміністратор Exchange знайшов винуватця. Ми використовуємо O365, але сервер Exchange був у гібридному середовищі. Хоча обліковий запис, який ми намагалися використати, синхронізований з Azure AD і мав дійсну ліцензію O365, чомусь поштова скринька все ще знаходилась на гібридному сервері Exchange - не в Exchange Online. Після того як адміністратор обміну використовував команду "Перемістити поштову скриньку" для переміщення поштової скриньки з гібридного сервера обміну на O365, ми могли використовувати код для надсилання електронних листів за допомогою o365.


-1

Підготовка: 1. Хост віртуальний сервер SMTP порт по- замовчуванням 25 2. HostB це робоче місце, на якому я відправити пошту з SmtpClient і моделювати нестабільну мережу використовувати я незграбний

Випадок 1 Дано, якщо HostB - 2008R2 Коли я надсилаю електронний лист. Потім ця проблема виникає.

Випадок 2 Дано, якщо HostB має версію 2012 року або вище, коли я надсилаю електронний лист. Потім пошту відправили.

Висновок: Ця першопричина пов’язана з Windows Server 2008R2.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.