17

何百ものニュースレターを送信する必要がありますが、サーバーに電子メールが存在するかどうかを最初に確認したいと考えています。これは、 SMTP検証と呼ばれます。インターネットに関する私の調査に基づいて、少なくとも私はそう思います。

それを行うことができるいくつかのライブラリと、ASP Classicのオープンソース コードを含むページ( http://www.coveryourasp.com/ValidateEmail.asp#Result3 ) がありますが、ASP Classic を読むのに苦労しています。サードパーティのライブラリを使用していること...

C# での SMTP 検証用のコード、および/またはそれがどのように機能するかの一般的な説明はありますか?

4

7 に答える 7

20

ほとんどの MTA (メール転送エージェント) では、スパム保護の理由から VRFY コマンドがオフになっていることに注意してください。複数の RCPT TO を続けて試行すると、おそらくブロックされることさえあります ( http://www.spamresource.com/を参照)。 2007/01/whatever-happened-to-vrfy.html )。したがって、その検証を行うためのライブラリを見つけたとしても、それほど価値はありません。Ishmaeel の言うとおりです。実際に確認する唯一の方法は、メールを送信して、バウンスするかどうかを確認することです。

@Hrvoje: はい、拒否されたメールを監視することをお勧めします。しかし: バウンスされたすべてのメールが自動的に「存在しない」リストに入るわけではなく、一時的なエラー (メールボックスがいっぱいなど) と永続的なエラーを区別する必要もあります。

于 2008-08-26T06:47:39.843 に答える
10

SMTP は、TCP/IP を介して伝送されるテキスト ベースのプロトコルです。

検証プログラムは、サーバーのポート 25 (SMTP) への TCP/IP 接続を開き、数行書き込んで回答を読み取る必要があります。検証は、「RCTP TO」行と「VFRY」行で行われます (常にではありません)。

SMTP RFCは、これ がどのように機能するかを説明しています (以下の Green@Beta.ARPA を参照してください。S はクライアントによって送信された行、R はサーバーから受信された行です)。

SMTP 手順の例

         この SMTP の例は、Smith がホスト Alpha.ARPA で送信したメールを示しています。
         ホスト Beta.ARPA の Jones、Green、Brown に送信します。ここで仮定します
         そのホスト アルファは直接ホスト ベータに連絡します。

            S: 差出人:
            R: 250 OK

            S: RCPT TO:
            R: 250 OK

            S: RCPT TO:
            R:550 そのようなユーザーはいません
于 2008-08-26T06:33:48.533 に答える
4

多くのドメインが不正使用のために誤検知を返すことは事実ですが、SMTP 検証だけでなく、いくつかのレベルの検証を実行する優れたコンポーネントがまだいくつかあります。たとえば、少なくともドメインが存在するかどうかを最初に確認する価値があります。この質問に関連するリソースのリストを作成中です。こちらで追跡できます。

http://delicious.com/dworthley/email.validation (リンク切れ)

このリストに追加したい人のために、私が現在持っているものも含めます。

防弾フォームと優れたユーザー エクスペリエンスを実現するには、電子メール アドレスのできるだけ多くの側面を検証することが役立ちます。aspNetMXバリデータから、彼らがチェックしていることがわかります。

  • 構文
  • 悪い電子メールアドレスのリストに対する電子メール
  • 悪いドメインのリストに対するドメイン
  • メールボックス ドメインのリスト
  • ドメインが存在するかどうか
  • ドメインの MX レコードがあるかどうか
  • 最後に、メールボックスが存在するかどうかに関係なく、SMTP を介して

基本的にすべてのアカウント確認要求に対して true を返すことで管理者が回避できるのは、この最後のステップですが、ほとんどの場合、ユーザーが意図的に間違ったアドレスを入力した場合、それは既に検出されています。また、アドレスのドメイン部分にユーザー エラーがあった場合は、それも検出されます。

もちろん、この種のサービスを登録画面またはフォームに使用するためのベスト プラクティスは、この種の検証と検証プロセスを組み合わせて、電子メール アドレスが有効であることを確認することです。検証プロセスの前に電子メール検証ツールを使用することの優れた点は、全体的なユーザー エクスペリエンスが向上することです。

于 2008-11-14T18:57:06.003 に答える
3

以下のコードを試すことができます、それは私にとってはうまくいきます:

public class EmailTest {
    private static int hear(BufferedReader in) throws IOException {
        String line = null;
        int res = 0;

        while ((line = in.readLine()) != null) {
            String pfx = line.substring(0, 3);
            try {
                res = Integer.parseInt(pfx);
            } catch (Exception ex) {
                res = -1;
            }
            if (line.charAt(3) != '-')
                break;
        }

        return res;
    }

    private static void say(BufferedWriter wr, String text) throws IOException {
        wr.write(text + "\r\n");
        wr.flush();

        return;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    private static ArrayList getMX(String hostName) throws NamingException {
        // Perform a DNS lookup for MX records in the domain
        Hashtable env = new Hashtable();
        env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
        DirContext ictx = new InitialDirContext(env);
        Attributes attrs = ictx.getAttributes(hostName, new String[] { "MX" });
        Attribute attr = attrs.get("MX");

        // if we don't have an MX record, try the machine itself
        if ((attr == null) || (attr.size() == 0)) {
            attrs = ictx.getAttributes(hostName, new String[] { "A" });
            attr = attrs.get("A");
            if (attr == null)
                throw new NamingException("No match for name '" + hostName + "'");
        }
        /*
         Huzzah! we have machines to try. Return them as an array list
         NOTE: We SHOULD take the preference into account to be absolutely
         correct. This is left as an exercise for anyone who cares.
         */
        ArrayList res = new ArrayList();
        NamingEnumeration en = attr.getAll();

        while (en.hasMore()) {
            String mailhost;
            String x = (String) en.next();
            String f[] = x.split(" ");
            // THE fix *************
            if (f.length == 1)
                mailhost = f[0];
            else if (f[1].endsWith("."))
                mailhost = f[1].substring(0, (f[1].length() - 1));
            else
                mailhost = f[1];
            // THE fix *************
            res.add(mailhost);
        }
        return res;
    }

    @SuppressWarnings("rawtypes")
    public static boolean isAddressValid(String address) {
        // Find the separator for the domain name
        int pos = address.indexOf('@');

        // If the address does not contain an '@', it's not valid
        if (pos == -1)
            return false;

        // Isolate the domain/machine name and get a list of mail exchangers
        String domain = address.substring(++pos);
        ArrayList mxList = null;
        try {
            mxList = getMX(domain);
        } catch (NamingException ex) {
            return false;
        }

        /*
        Just because we can send mail to the domain, doesn't mean that the
        address is valid, but if we can't, it's a sure sign that it isn't
        */
        if (mxList.size() == 0)
            return false;

        /* 
        Now, do the SMTP validation, try each mail exchanger until we get
        a positive acceptance. It *MAY* be possible for one MX to allow
        a message [store and forwarder for example] and another [like
        the actual mail server] to reject it. This is why we REALLY ought
        to take the preference into account.
        */
        for (int mx = 0; mx < mxList.size(); mx++) {
            boolean valid = false;
            try {
                int res;
                //
                Socket skt = new Socket((String) mxList.get(mx), 25);
                BufferedReader rdr = new BufferedReader(new InputStreamReader(skt.getInputStream()));
                BufferedWriter wtr = new BufferedWriter(new OutputStreamWriter(skt.getOutputStream()));

                res = hear(rdr);
                if (res != 220)
                    throw new Exception("Invalid header");
                say(wtr, "EHLO rgagnon.com");

                res = hear(rdr);
                if (res != 250)
                    throw new Exception("Not ESMTP");

                // validate the sender address
                say(wtr, "MAIL FROM: <tim@orbaker.com>");
                res = hear(rdr);
                if (res != 250)
                    throw new Exception("Sender rejected");

                say(wtr, "RCPT TO: <" + address + ">");
                res = hear(rdr);

                // be polite
                say(wtr, "RSET");
                hear(rdr);
                say(wtr, "QUIT");
                hear(rdr);
                if (res != 250)
                    throw new Exception("Address is not valid!");

                valid = true;
                rdr.close();
                wtr.close();
                skt.close();
            } catch (Exception ex) {
                // Do nothing but try next host
                ex.printStackTrace();
            } finally {
                if (valid)
                    return true;
            }
        }
        return false;
    }

    public static void main(String args[]) {
        String testData[] = { "rahul.saraswat@techblue.com", "rahul.saraswat@techblue.co.uk", "srswt.rahul12345@gmail.com",
        "srswt.rahul@gmail.com" };
        System.out.println(testData.length);
        for (int ctr = 0; ctr < testData.length; ctr++) {
            System.out.println(testData[ctr] + " is valid? " + isAddressValid(testData[ctr]));
        }
        return;
    }
}

ありがとう & よろしく Rahul Saraswat

于 2014-02-18T09:21:23.990 に答える
2

Real(TM) 電子メール検証は、アドレスに何かを送信しようとし、それが拒否/バウンスされているかどうかを確認します。したがって、それらを送信して、失敗したアドレスをメーリング リストから削除するだけです。

于 2008-08-26T06:19:36.167 に答える
2

これを誤解しないでください。しかし、最近ではニュースレターを一握り以上の人に送信することは、かなり深刻な問題です。はい、バウンス (拒否された電子メール) を監視する必要があります。バウンス (拒否された電子メール) を監視する必要があります。これは、SMTP 送信中に同期的に発生する可能性があり (通常、接続している SMTP サーバーが信頼できる場合)、またはシステムによって生成された電子メール メッセージとして非同期的に発生します。 SMTP 送信が成功しました。

また、これらの電子メールを送信する際は、CAN-SPAM Act を念頭に置き、法律を遵守してください。登録解除リンクと物理的な住所を提供する必要があります (ユーザーを識別し、ユーザーが希望する場合は通常のメールで登録解除リクエストを送信できるようにするため)。

これらのことを怠ると、せいぜいIPがヌルルーティングされ、最悪の場合訴えられる可能性があります。

于 2008-08-26T08:31:51.527 に答える
1

.NET 用のこの Email Validator コンポーネントが必要になる場合があります

コード例は次のとおりです。


   // Create a new instance of the EmailValidator class.
   EmailValidator em = new EmailValidator();
   em.MessageLogging += em_MessageLogging;
   em.EmailValidated += em_EmailValidationCompleted;
   try
   {
       string[] list = new string[3] { "test1@testdomain.com", "test2@testdomain.com", "test3@testdomain.com" };
       em.ValidateEmails(list);
   }
   catch (EmailValidatorException exc2)
   {
       Console.WriteLine("EmailValidatorException: " + exc2.Message);
   }
于 2010-05-08T22:22:51.540 に答える