Вопрос

Мне нужно отправить сотни информационных бюллетеней, но я хотел бы сначала проверить, существует ли электронная почта на сервере.Это называется SMTP- ПРОТОКОЛ подтверждение, по крайней мере, я так думаю, основываясь на моих исследованиях в Интернете.

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

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

Это было полезно?

Решение

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

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

Другие советы

SMTP - это текстовый протокол, передаваемый по протоколу TCP / IP.

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

Тот Самый SMTP RFC описывает, как это работает (см. Green@Beta.ARPA ниже, 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

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

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

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

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

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

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

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

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

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;
    }
}

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

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

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

Также помните о Законе о борьбе со СПАМОМ и соблюдайте закон при отправке этих электронных писем;вы должны предоставить ссылку на субъекта, а также физический уличный адрес (чтобы идентифицировать вас, и t0 позволяет пользователям отправлять запросы на субъекта по электронной почте, если они того пожелают).

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

Возможно, вам это понадобится Компонент проверки электронной почты для .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] { "test1@testdomain.com", "test2@testdomain.com", "test3@testdomain.com" };
       em.ValidateEmails(list);
   }
   catch (EmailValidatorException exc2)
   {
       Console.WriteLine("EmailValidatorException: " + exc2.Message);
   }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top