Подтвердить что ты не робот

Email SMTP validator

Мне нужно отправить сотни бюллетеней, но сначала хочу проверить, существует ли на сервере электронная почта. Он назывался SMTP, по крайней мере, я думаю, это основано на моих исследованиях в Интернете.

Есть несколько библиотек, которые могут это сделать, а также страницу с открытым исходным кодом в ASP Classic (http://www.coveryourasp.com/ValidateEmail.asp#Result3), но мне сложно читать ASP Classic, и кажется, что он использует некоторую стороннюю библиотеку...

Есть ли какой-нибудь код для проверки SMTP в С# и/или общее объяснение того, как он работает?

4b9b3361

Ответ 1

Имейте в виду, что большинство агентов MTA (агент передачи почты) отключит команду VRFY для защиты от спама, они, вероятно, даже заблокируют вас, если вы попробуете несколько RCPT TO в строке (см. http://www.spamresource.com/2007/01/whatever-happened-to-vrfy.html). Поэтому, даже если вы найдете библиотеку для этой проверки, она не будет стоить много. Ishmaeel прав, единственный способ действительно узнать, отправляет электронное письмо и видит, отскакивает оно или нет.

@Hrvoje: Да, я предлагаю вам отслеживать отклоненные письма. НО: не все отскоченные письма должны автоматически заканчиваться на вашем "не существует" -list, вам также необходимо различать временные (например, почтовый ящик) и постоянные ошибки.

Ответ 2

SMTP - это текстовый протокол, переносимый через TCP/IP.

Ваша программа проверки должна открыть TCP/IP-соединение с портом сервера 25 (SMTP), записать в несколько строк и прочитать ответ. Проверка выполняется (но не всегда) на линии "RCTP TO" и в строке "VFRY".

SMTP RFC описывает, как это работает (см. [email protected] ниже, S - строки, отправленные клиентом, R - полученные линии с сервера):

Example of the SMTP Procedure

         This SMTP example shows mail sent by Smith at host Alpha.ARPA,
         to Jones, Green, and Brown at host Beta.ARPA.  Here we assume
         that host Alpha contacts host Beta directly.

            S: MAIL FROM:
            R: 250 OK

            S: RCPT TO:
            R: 250 OK

            S: RCPT TO:
            R: 550 No such user here

Ответ 3

Хотя верно, что многие домены вернут ложные срабатывания из-за злоупотребления, все еще есть замечательные компоненты, которые будут выполнять несколько уровней проверки за пределами только проверки SMTP. Например, стоит сначала проверить, чтобы увидеть, существует ли, по крайней мере, домен. Я занимаюсь составлением собственного списка ресурсов, связанных с этим вопросом, которые вы можете отслеживать здесь:

http://delicious.com/dworthley/email.validation

Для тех, кто может захотеть добавить в этот список, я также включу то, что у меня здесь есть:

Для пуленепробиваемой формы и отличного пользовательского опыта полезно проверить как можно больше аспектов адреса электронной почты. Я вижу из aspNetMX валидатор, который они проверяют:

  • синтаксис
  • письмо против списка неправильных адресов электронной почты
  • домен против списка плохих доменов
  • список доменов почтовых ящиков
  • существует ли домен
  • есть ли записи MX для домена
  • и, наконец, через SMTP, существует ли почтовый ящик

Это последний шаг, который могут быть обойден администраторами, возвращая true в основном все запросы проверки учетной записи, но в большинстве случаев, если пользователь намеренно ввел плохой адрес, он уже был пойман. И если это была ошибка пользователя в доменной части адреса, это также будет найдено.

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

Ответ 4

Вы можете попробовать приведенный ниже код, он отлично работает для меня:

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 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 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: <[email protected]>");
                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[] = { "[email protected]", "[email protected]", "[email protected]",
        "[email protected]" };
        System.out.println(testData.length);
        for (int ctr = 0; ctr < testData.length; ctr++) {
            System.out.println(testData[ctr] + " is valid? " + isAddressValid(testData[ctr]));
        }
        return;
    }
}

Спасибо и с уважением Рахул Сарасват

Ответ 5

Проверка подлинности электронной почты Real (TM) пытается отправить что-то по адресу и увидеть, отклонено ли/отброшено. Таким образом, вам просто нужно отправить их и удалить адреса, которые не совпадают с вашим списком рассылки.

Ответ 6

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

Также учитывайте Закон CAN-SPAM и соблюдайте закон при отправке этих писем; вам необходимо предоставить несовместимую ссылку, а также физический адрес на улице (как для вас, так и для t0 разрешить пользователям отправлять необоснованные запросы через уличную почту, если они этого захотят).

Неспособность сделать это может привести к тому, что ваш IP-адрес будет перенаправлен в лучшем случае и в худшем случае подаст иск.

Ответ 7

Вам может понадобиться этот компонент Email Validator для .NET

Вот пример кода:


   // 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] { "[email protected]", "[email protected]", "[email protected]" };
       em.ValidateEmails(list);
   }
   catch (EmailValidatorException exc2)
   {
       Console.WriteLine("EmailValidatorException: " + exc2.Message);
   }

Ответ 8

Я пробовал некоторые сервисы MTA и у меня есть несколько заметок, особенно вы должны уменьшить первоначальную безопасность Gmail, чтобы иметь возможность рассылать много сообщений без проверки подлинности с помощью какого-либо инструмента. Что касается Bounces Email, я обнаружил, что есть инструмент, который поможет вам пересчитать Bounces of Email при каждой отправке. А вот некоторые ссылки, на которые вы можете ссылаться: https://www.componentpro.com/products/email-validator - https://www.componentpro.com/products/mail - https://www.codeultimate.com/продукты/почта - https://www.codeultimate.com/products/email-validator - https://www.atp-inc.net/products/mail - https://www.atp-inc.net/products/электронная почта-валидатор