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

編集:Super Reduxバージョン

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


大量のパケットスニッフィングの後、私はそれを理解しました。まず、ここに短い答えがあります:

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

次に、将来この問題に遭遇した人のための簡単なSMTP履歴レッスン:

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

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


接続しているサーバーに同じ問題があるかどうかを確認するにはどうすればよいですか?yahooやgmailでSmtpClientを使用して、説明されているエラーを取得しようとしています。2013 Exchangeサーバーに対して試行すると、私のコードは正常に動作します。
raider33 14年

11
テストする最も簡単な方法は、465ではなくポート587を使用することです。一部のSMTPサーバーは465(場合によっては25)でTLSをサポートしますが、TLSのサポートに必要なのはポート587だけです。さらに、ポート465の使用は1998年以降非推奨になっています(en.wikipedia.org/wiki/SMTPS)が、実際には多くのサーバーでレガシークライアントに対して有効になっています。
Jake C

1
はい、587に変更するとうまくいきました。私を正しい方向に向けてくれてありがとう。
raider33 2014年

2
smtp.att.yahaoo.comが465を使用すると言っていますが、587は機能します。
Sam

1
実際の解決策については、暗黙のSSLをサポートする(非推奨の)System.Web.Mailの使用について、stackoverflow.com / a / 1014876/247702を参照してください。
user247702

20

ポートを465から587に変更すれば動作します。


3
何が起こったのかはわかりませんが、これでGmailのSMTPを使用できます。これが機能する理由を説明できますか?
クリスモグラム2016年

20

この投稿を見つけて解決策を探していて、Azure経由でSMTP sendgridを設定した人は誰でも。

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

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

お役に立てれば!


2
これはばかげているように見えるかもしれませんが、パスワードがSMTP SendGridセットアップに対して正しいかどうかを確認する必要があるかもしれません。私たちのセットアップは当初は機能していたが、ある日、OPの例外メッセージを受け取り始めた。WWWでの検索では、最終的にパスワードが正しくないことが判明したときに、他のSMTPサーバーの構成を参照することがほとんどでした。チームの誰かが、構成ファイルのパスワードを、最初の文字が大文字ではないバリエーションに変更しました。
methon.dagger 2017

1
私の場合、ユーザー名は正しくなく、タイプミスがありました。ただし、パスワードが間違っていると、「トランスポート接続からデータを読み取れません:net_io_connectionclosed」が発生する場合もあります。エラー。したがって、ユーザー名とパスワードの両方を確認してください。Azureユーザーの場合、ユーザー名の形式は "azure_guid-withoutdashes@azure.com"(例:azure_e9e062db4bfd491296bec77bcff49ed9@azure.com)
Raj Rao

10

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


ビルに感謝します。これはまだ私の標準のGmailアカウントで動作します。「安全性の低いアプリ」設定を使用しない場合は、OAuth2 2部認証を使用する必要があります。これは、Webサイトから確認メールを送信するだけの場合には実用的ではありません。
ダンランドルフ

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 Clientは、セキュリティ上の問題のため、Microsoftでの使用は推奨されておらず、代わりにMailKitを使用する必要があります。Mailkitを使用すると、問題(ライセンスの問題)の根本的な原因を見つけることが理解できる明確なエラーメッセージが表示されました。メールキットは、Nugetパッケージとしてダウンロードして入手できます。

詳細については、Smtpクライアントに関するドキュメントをご覧ください: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 = "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ハンドシェイクがない場合は接続を閉じる


これは単なるデフォルトの.NET SmtpClientライブラリであり、暗号化をサポートし、サーバーは暗号化を必要とし、私はを設定しましたclient.EnableSssl = true;。私はWiresharkでこれをもう少し説得するつもりですが。
ジェイクC

3

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


2

コメントでジョクルが言ったことを向上させるために、私はこのスレッドで言及されているすべてを実行して三振していました...私は繰り返し実行されるループにあったためです。ループを初めて通過した後、失敗する場合があります。常に最初から最後まで機能しました。

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

私の場合、解決策は、ループ内で毎回SmtpClientが確実に破棄されるようにすることです(using()ステートメントを使用するか、手動で破棄することにより)。SmtpClientオブジェクトがループ内で暗黙的に破棄されている場合でも、.NETは、次の試行と競合するものを残しておくように見えます。




1

上記のすべての解決策がうまくいかない場合は、次のファイルをサーバーに更新してみてください(つまり、発行することで、それより前のビルドが役立ちます)。

bin-> projectname.dll 

更新後、このエラーが表示されます。私がこの解決策で解決したように。


1
驚くべきことに、これは私にとってうまくいきました!安全でないアプリの許可がオンで、ポートはすでに587に設定されていました。
TechyGypo 2017

おかげで、この問題の原因は私だけではないことに気づきました。お力になれて、嬉しいです。
Ajay Kumar

1

私の場合、顧客はSMTP設定に新しいIPアドレスを追加するのを忘れていました。SMTPをセットアップするサーバーでIIS 6.0を開き、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ブロックで包む必要があります
ジョッカル


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

私の場合、WebサーバーのIPがメールサーバーでブロックされていましたが、ホスティング会社によってブロックを解除してホワイトリストに登録する必要があります。また、ポート587を使用します。


0

メールサーバーがGmail(smtp.google.com)の場合、メッセージの制限に達したときにこのエラーが発生します。Gmailでは、24時間あたり最大2000件のメッセージをSMTP経由で送信できます。


0

SSLでポート587を使用してsmtp.office365.comを使用しているときに、この問題に遭遇しました。portal.office.comを使用してアカウントにログインでき、アカウントにライセンスがあることを確認できました。しかし、メールを送信するコードを実行すると、net_io_connectionclosedエラーが発生し続けました。

理解するのに少し時間がかかりましたが、Exchange管理者が原因を見つけました。O365を使用していますが、Exchangeサーバーはハイブリッド環境にありました。使用しようとしたアカウントはAzure ADに同期され、有効なO365ライセンスがありましたが、何らかの理由でメールボックスがハイブリッドExchangeサーバー(Exchangeオンラインではない)にまだ存在していました。Exchange管理者が「Move-Mailbox」コマンドを使用してメールボックスをハイブリッドExchangeサーバーからO365に移動した後、コードを使用してo365を使用してメールを送信できます。


-1

準備:1. HostAは、デフォルトポート25のSMTP仮想サーバーです。2. HostBは、SmtpClientでメールを送信し、不安定なネットワークシミュレートするワークステーション です。

HostBが2008R2の場合にメールを送信した場合のケース1 その後、この問題が発生します。

事例2 メールを送信するときにHostBが2012以降のバージョンである場合に発生します。その後、メールを送信しました。

結論:この根本原因は、Windows Server 2008R2に関連しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.