web-dev-qa-db-ja.com

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("[email protected]", "[email protected]", "Subject", "Body");

テスト環境ではコードは正常に機能しますが、実稼働SMTPサーバーを使用すると、コードはSmtpException「メールの送信に失敗しました」というエラーで失敗します。内部のIOException「トランスポート接続からデータを読み取れません:net_io_connectionclosed」。

ファイアウォールは問題ではないことを確認しました。ポートは、クライアントとサーバー間で正常に開きます。このエラーを他に何がスローするかはわかりません。

93
Jake C

編集:Super Reduxバージョン

465の代わりにポート587を試してください。ポート465は技術的に非推奨です。


大量のパケットスニッフィングの後、私はそれを見つけました。まず、簡単な答えを次に示します。

.NET SmtpClientonlyは、STARTTLSによる暗号化をサポートします。 EnableSslフラグが設定されている場合、サーバーはSTARTTLSでEHLOに応答する必要があります。そうでない場合、例外がスローされます。詳細については、 MSDN のドキュメントを参照してください。

第二に、将来この問題に出くわした人のための簡単なSMTP履歴レッスン:

かつて、サービスも暗号化を提供したいと考えていたときに、別のポート番号が割り当てられ、そのポート番号ですぐにSSL接続を開始しました。時間が経つにつれて、1つのサービスに2つのポート番号を無駄にするのはばかげていることに気づき、STARTTLSを使用して同じポートでプレーンテキストと暗号化を許可する方法を考案しました。通信はプレーンテキストを使用して開始され、STARTTLSコマンドを使用して暗号化された接続にアップグレードします。 STARTTLSはSMTP暗号化の標準になりました。残念ながら、新しい標準が実装されると常に起こるように、そこにあるすべてのクライアントとサーバーとの互換性の寄せ集めがあります。

私の場合、ユーザーはソフトウェアを即時SSL接続を強制するサーバーに接続しようとしました。これは、Microsoftが.NETでサポートしていない従来の方法です。

164
Jake C

ポートを465から587に変更すると、動作します。

17
ADM-IT

解決策を探しているこの投稿に出くわし、Azure経由でSMTP sendgridを設定している場合

ユーザー名は、Azureでsendgridオブジェクトを作成したときに設定したユーザー名ではありません。ユーザー名を見つけるには;

  • Azureでsendgridオブジェクトをクリックし、[管理]をクリックします。 SendGridサイトにリダイレクトされます。
  • メールを確認して、そこに表示されるユーザー名をコピーしてください。これは自動生成されたユーザー名です。
  • SendGridのユーザー名をweb.configファイルのSMTP設定に追加します。

お役に立てれば!

16
nologo

また、Gmailアカウントの「安全性の低いアプリ」設定を変更する必要がある場合もあります。 EnableSsl、ポート587を使用し、「安全性の低いアプリ」を有効にします。安全性の低いアプリの部分をグーグルで検索すると、アカウントのページに直接リンクするグーグルヘルプページがあります。それが私の問題でしたが、上記のすべての答えのおかげで、すべてが現在機能しています。

8
Bill Mahoney

上記のすべての回答を試しましたが、Office 365アカウントでこのエラーが発生します。安全性の低いアプリを許可する場合、コードはGoogleアカウントおよびsmtp.gmail.comで正常に機能するようです。

私が試すことができる他の提案はありますか?

ここに私が使用しているコードがあります

int port = 587;
string Host = "smtp.office365.com";
string username = "[email protected]";
string password = "password";
string mailFrom = "[email protected]";
string mailTo = "[email protected]";
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 Clientは、セキュリティの問題があるため、Microsoftによる使用は推奨されておらず、代わりにMailKitを使用する必要があります。 Mailkitを使用すると、問題の根本原因(ライセンスの問題)を見つけることが理解できる、より明確なエラーメッセージが得られました。 Mailkitは、 Nuget パッケージとしてダウンロードして入手できます。

詳細については、Smtp Clientに関するドキュメントを参照してください。 https://docs.Microsoft.com/es-es/dotnet/api/system.net.mail.smtpclient?redirectedfrom=MSDN&view=netframework-4.7.2 =

MailKitでSmtpClientを実装した方法は次のとおりです。

        int port = 587;
        string Host = "smtp.office365.com";
        string username = "[email protected]";
        string password = "password";
        string mailFrom = "[email protected]";
        string mailTo = "[email protected]";
        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);
        }
5
Martin Jaensson

SMTPライブラリは暗号化された接続をサポートしていますか?メールサーバーは安全なTLS接続を期待している可能性があるため、TLSハンドシェイクがない場合に接続を閉じる

3
1234varun

同じボックスでSMTPサーバーを使用していて、SMTPが「割り当てられた」ではなくIPアドレスにバインドされている場合、SMTPが現在機能していないIPアドレス(127.0.0.1など)を使用しようとするため失敗するに。

2
Josiah

Jocullがコメントで言及したことを高めるために、私はこのスレッドですべての言及を行い、ストライクアウトしました...私のものは繰り返し実行されるループにあったためです。ループを初めて通過した後、失敗することがありました。常にループを最初からやりました。

明確にするために、ループにはSmtpClientの作成が含まれ、その後正しいデータで.Sendを実行します。 SmtpClientは、エラーをキャッチし、ループの最後の前にオブジェクトが確実に破棄されるようにするために、try/catchブロック内に作成されました。

私の場合、解決策は、SmtpClientがループ内の各時間の後に(using()ステートメントを介して、または手動で破棄することによって)破棄されるようにすることでした。 SmtpClientオブジェクトがループ内で暗黙的に破棄されている場合でも、.NETは次の試行と競合するために物事を放置しているように見えます。

1
Andy

上記のすべてのソリューションが機能しない場合は、次のファイルをサーバーに更新してみてください(つまり、公開することで、その前のビルドが役立ちます)。

bin-> projectname.dll 

更新後、このエラーが表示されます。私はこのソリューションで解決しました。

1
Ajay Kumar

Outlookの場合、私にエラーを与えていない次の設定を使用してください

SMTPサーバー名smtp-mail.Outlook.com

SMTPポート587

0
Hisham shahid

ポート番号を465から587に変更します

0

このエラーは非常に一般的です。メールサーバーが正しくないなど、多くの理由が考えられます。一部のホスティング会社はmail.domainname形式を使用しています。ドメイン名を使用するだけでは機能しません。資格情報を確認します必要に応じてホスト名ユーザー名パスワードホスティング会社に確認してください。

<smtp from="[email protected]">
        <!-- Uncomment to specify SMTP settings -->
        <network Host="domain.com" port="25" password="[email protected]" userName="[email protected]"/>
      </smtp>
    </mailSettings>
0
Jin Thakur

私の場合、顧客はSMTP設定に新しいIPアドレスを追加するのを忘れていました。 smtpをセットアップするサーバーでIIS 6.0を開き、Smtp仮想サーバーを右クリックして、[プロパティ]、[アクセス]タブを選択し、[接続]をクリックして、新しいサーバーのIPアドレスを追加します。次に、[中継]をクリックし、新しいサーバーのIPアドレスも追加します。これで問題が解決しました。

0
Nora

これを試してください:これは、複数のユーザーにメールを送信するために使用しているコードです。

 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;
            }
        }
    }
0
yasmuru
//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;
0
SelakaN