- PR -

System.Net.Mail.SmtpClient と POP3 Before Smtp について

1
投稿者投稿内容
らいあん
会議室デビュー日: 2008/06/27
投稿数: 2
投稿日時: 2008-06-27 19:16

お世話になります。
新米プログラマーのらいあんと申します。

現在、ASP .NET(VS2005)で顧客専用サイトを開発しているのですが、
サイトの一部であるメール送信機能について問題があり、困っています。

以下、ソースです。

=== POP認証部分 ===
System.Net.Sockets.TcpClient pop = new System.Net.Sockets.TcpClient();
pop.SendTimeout = 10000;
pop.ReceiveTimeout = 10000;
pop.Connect(SMTPサーバー, 110);

NetworkStream nws = pop.GetStream();
StreamWriter sw = new StreamWriter(nws);
StreamReader sr = new StreamReader(nws);
String res = string.Empty;

sw.NewLine = "\r\n";
res += sr.ReadLine();

sw.AutoFlush = true;
sw.WriteLine("USER {0}", ユーザー名);
res += sr.ReadLine();
sw.WriteLine("PASS {0}", パスワード);
res += sr.ReadLine();
sw.WriteLine("QUIT");
res += sr.ReadLine();
nws.Close();
pop.Close();

=== メール送信部分 ===
System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage(差出人アドレス, 送信先アドレス);
message.Subject = 件名;
message.Body = 本文;
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(SMTPサーバー, 25);
//メール送信
client.Send(message);


上記の方法でメール送信を行っているのですが、実在しないメールアドレスに送信しようとすると
client.Send(message)部分で、"すべての受信者には送信できません。"という例外エラーが起こってしまいます。

POP認証部分があやしいと思い、デバッグしながら"res"の値を確認しましたが、エラーは起こっていないようです。
また、そのエラーが発生するのは初回だけで、続けざまに同じ条件で送信すると成功します。
(30分ほど経過した後は、再び同じエラーが発生します)

SMTPサーバー側の動作として、POP認証が成功したIPアドレスを保持し、一定時間だけ
メール送信を許可するようですが、こちらのIPアドレスが「送信を許可するIPアドレス」
としてSMTPサーバー上で扱われるようになる前に、メールが送信されてしまっていることが
原因ではないかと考えています。


SMTPサーバーを管理しているISPに確認したところ、IPアドレスの保持時間は約30分とのことでした。
現在のところ、この問題の回避策として、
「メール送信ボタンを配置しているページのページロードイベント時に予めPOP認証を済ましておく」
という方法をとっており、エラーは発生しなくなりましたが、
果たしてこの方法が正しいのかどうか、判断がつかず困っております。

他に適切な対処方法があれば、ご教授いただければと思います。
また、本当に上記のことが原因なのでしょうか?

宜しくお願い致します。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2008-07-06 17:20
引用:

らいあんさんの書き込み (2008-06-27 19:16) より:


SMTPサーバー側の動作として、POP認証が成功したIPアドレスを保持し、一定時間だけ
メール送信を許可するようですが、こちらのIPアドレスが「送信を許可するIPアドレス」
としてSMTPサーバー上で扱われるようになる前に、メールが送信されてしまっていることが原因ではないかと考えています。


SMTPサーバーを管理しているISPに確認したところ、IPアドレスの保持時間は約30分とのことでした。
現在のところ、この問題の回避策として、
「メール送信ボタンを配置しているページのページロードイベント時に予めPOP認証を済ましておく」
という方法をとっており、エラーは発生しなくなりましたが、
果たしてこの方法が正しいのかどうか、判断がつかず困っております。


 POP Before SMTP<live.com> という奴ですね。
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2008-07-06 18:35
引用:

らいあんさんの書き込み (2008-06-27 19:16) より:
SMTPサーバー側の動作として、POP認証が成功したIPアドレスを保持し、一定時間だけ
メール送信を許可するようですが、こちらのIPアドレスが「送信を許可するIPアドレス」
としてSMTPサーバー上で扱われるようになる前に、メールが送信されてしまっていることが
原因ではないかと考えています。



もしそれが本当なら、
POP認証してからしばらく待てば正常に送信できるということですよね。

ならば
引用:

「メール送信ボタンを配置しているページのページロードイベント時に予めPOP認証を済ましておく」


この方法はなかなか頭のよい方法だと思います。

この方法の問題は
1 無駄にPOP認証が行われてしまう可能性がある点
2 ページを表示して30分以上待つとメールが送信できなくなってしまう点
ですね。

引用:

果たしてこの方法が正しいのかどうか、判断がつかず困っております。


上記の2つが問題ないならば、それでいいと思いますが、
私ならその方法はとりません。
無駄に認証を行うのはセキュリティ上も好ましくありませんし、
30分ほどページを放置するのはよくあることなので。

また、今後メールを送信したい用途があり、コードを再利用したい場合、
「事前にPOP認証しておくこと」というのを覚えておかないといけません。

引用:

他に適切な対処方法があれば、ご教授いただければと思います。


本当に「ただ待てばいい」のであれば、
POP認証したあと適切な時間SleepなどでWaitすればよいだけかと思います。
Retryするというのも手です。

組み合わせて
POP認証->(Wait)->SMTP送信->Wait->SMTP送信->Wait->SMTP送信->例外
見たいなフローにしておけばよいかと思いますが。

引用:

また、本当に上記のことが原因なのでしょうか?


本当にそれが原因かどうかは示された内容だけではなんとも言えないかと思います。
SMTPサーバーのソフトもわかりませんし。

でも同様の問題は聞いたことがあります。
その問題の原因はらいあんさんの推測と同じでしたよ。
らいあん
会議室デビュー日: 2008/06/27
投稿数: 2
投稿日時: 2008-07-07 13:30
Jittaさん、れいさん、返信ありがとうございました。

引用:
れいさんの書き込み (2008-07-06 18:35) より:

「メール送信ボタンを配置しているページのページロードイベント時に予めPOP認証を済ましておく」

この方法の問題は
1 無駄にPOP認証が行われてしまう可能性がある点
2 ページを表示して30分以上待つとメールが送信できなくなってしまう点
ですね。


1については、やはり課題ですね。

2の問題については、そもそもセッションタイムアウトを20分間としていますので
現時点では問題ないかと思っていますが、POP認証に成功したIPアドレスの保持時間を
ISPが変更した場合に問題が起こると思います。。。


引用:
本当に「ただ待てばいい」のであれば、
POP認証したあと適切な時間SleepなどでWaitすればよいだけかと思います。


Sleepも試してみたのですが、500msの待機時間で成功する時もあれば、
1000msで失敗する時もあり、外部の環境にかなり影響を受けるようでした。
安全策をとって待機時間を長めに設定すると、レスポンス面でユーザビリティが
低下するため、断念しました。


引用:
Retryするというのも手です。
組み合わせて
POP認証->(Wait)->SMTP送信->Wait->SMTP送信->Wait->SMTP送信->例外
見たいなフローにしておけばよいかと思いますが。


提示して頂いた方法がやはり確実ですね。

大変勉強になりました。
どうもありがとうございました。

1

スキルアップ/キャリアアップ(JOB@IT)