SmtpException: не удается прочитать данные из транспортного соединения: net io connectionclosed


Я использую 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".

Я подтвердил, что брандмауэры не являются проблемой. Порт открывается просто отлично между клиентом и сервером. Я не уверен, что еще может бросить эту ошибку.

11 79

11 ответов:

EDIT: Super Redux Version

попробуйте порт 587 вместо 465. Порт 465 технически устарел.


после того, как куча пакет нюхают я понял это. Во-первых, вот короткий ответ:

интернет .Сети SmtpClientтолько поддерживает шифрование через STARTTLS. Если EnableSsl флаг установлен, сервер должен ответить на EHLO с помощью STARTTLS, иначе он выдаст исключение. Смотрите MSDN документация новые подробности.

в тот день, когда службы хотели также предложить шифрование, им был назначен другой номер порта, и на этом номере порта они сразу же инициировали SSL-соединение. Со временем они поняли, что глупо тратить два номера портов для одной службы, и они разработали способ для служб разрешить открытый текст и шифрование на одном и том же порту, используя STARTTLS. Связь начнется с использованием открытого текста, а затем используйте команду STARTTLS для обновления до зашифрованного соединения. STARTTLS, это стало стандартом для шифрования по протоколу SMTP. К сожалению, как это всегда бывает при внедрении нового стандарта, существует мешанина совместимости со всеми клиентами и серверами там.

в моем случае мой пользователь пытался подключить программное обеспечение к серверу, который вызывал немедленное соединение SSL, что является устаревшим методом, который не является поддерживается Microsoft in. NET.

измените порт с 465 на 587, и он будет работать.

для тех, кто натыкается на этот пост ищет решение, и вы настроили SMTP sendgrid через Azure.

имя пользователя не является именем пользователя, настроенным при создании объекта sendgrid в azure. Чтобы найти свое имя пользователя;

  • нажмите на свой объект sendgrid в azure и нажмите кнопку Управление. Вы будете перенаправлены на сайт статье.
  • подтвердите свою электронную почту, а затем скопируйте имя пользователя, отображаемое там.. это автоматически сгенерированное имя пользователя.
  • добавьте имя пользователя из SendGrid в настройки SMTP в интернете.конфигурационный файл.

надеюсь, что это помогает!

возможно, Вам также придется изменить настройку "менее безопасные приложения" в вашей учетной записи Gmail. EnableSsl, используйте порт 587 и включите "менее безопасные приложения". Если вы google менее безопасные приложения часть есть страницы справки google, которые свяжут вас прямо на страницу для вашей учетной записи. Это была моя проблема, но теперь все работает благодаря всем ответам выше.

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

Если вы используете SMTP-сервер в том же поле, и ваш SMTP привязан к IP-адресу вместо "любого назначенного", он может потерпеть неудачу, потому что он пытается использовать IP-адрес (например, 127.0.0.1), над которым SMTP в настоящее время не работает.

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

bin-> projectname.dll 

после обновления вы увидите эту ошибку. как я решил с этим решением.

//Try this out... Port 465 is not there anymore for use
     string emailFrom = "sender email here";
    string recieverEmail ="reciever email here";
            string subject = "subject here";
            string body = "message here";
            MailMessage maile = new MailMessage(emailFrom, recieverEmail, subject,body);
            SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
            client.Credentials = new System.Net.NetworkCredential("senders gmail account username here", "senders gmail account password here");
            client.EnableSsl = true;

чтобы поднять то, что джокулл упомянул в комментарии, я делал все упоминание в этой теме и вычеркивал... потому что мой был в цикле, который нужно было запускать снова и снова; после первого раза через цикл он иногда терпел неудачу. Всегда работал в первый раз через петлю.

чтобы быть ясным: цикл включает в себя создание SmtpClient, а затем делает .Отправить с правильными данными. SmtpClient был создан внутри блока try / catch, чтобы поймать ошибки и убедиться, что объект был уничтожен до нижней части петли.

в моем случае решение состояло в том, чтобы убедиться, что SmtpClient был удален после каждого раза в цикле (либо с помощью оператора (), либо с помощью ручного удаления). Даже если объект SmtpClient неявно уничтожается в цикле, .NET, похоже, оставляет вещи, лежащие вокруг, чтобы конфликтовать со следующей попыткой.

попробуйте это : вот код, который я использую для отправки электронной почты на несколько пользователей.

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

для outlook используйте следующий параметр, который не дает мне ошибку

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

SMTP порт 587