Конференция "Сети" » Подскажите как отправить письмо используя сокеты? [D7, WinXP]
 
  • belousov © (27.08.09 03:57) [20]
    Хотел бы продолжить тему... ситуация схожая... использую сервер исходящей почты smtp.mail.ru со своим аккаунтом. Использую ICS, т.к. с Indy проблем больше... Все замечательно отправляется и доходит и с кодировкой проблем нет, но вот когда посылаю письмо сразу нескольким людям(около 8 человек), то письма не доходят... я так понимаю, что mail.ru блокирует их отправку, принимает за смамство или что-то в этом роде... вот код:

    //если есть кому отправлять, то
    if ToComboBox.Text<>'' then
    begin
     CFSets := LoadCFS;
     // установка SMTP
     with CFSets.SMTP_Sets do
      begin
       SMTP.Host:= SMTP_Host;
       SMTP.SignOn := SMTP_Host;
       SMTP.Port:= inttostr(SMTP_Port);
       Smtp.AuthType:= smtpAuthLogin; // atNone
       Smtp.Username:= SMTP_Login;
       Smtp.Password:= SMTP_Password;
       domain := copy(SMTP_Host, 6, length(SMTP_Host));
       Smtp.FromName := SMTP_Login + '@' + domain;
      end;
     //коннектимся
     //SMTP.Open;
     // установка сообщения
     // тема
     Smtp.HdrSubject := SubjectEdit.Text;
     Smtp.HdrFrom := FromEdit.Text; // адрес отправителя
     Smtp.MailMessage.Text := MsgTextMemo.Text;
     //проверяем кому нужно отправить сообщение
     if AnsiUpperCase(ToComboBox.Text)=AnsiUpperCase('Всем одногрупникам') then
      begin
       //выставляем позицию
       MsgSendProgressBar.Position := 0;
       MsgSendProgressBar.Max := SResListBox.Count;
       //перебираем элементы списка
       for i := 0 to SResListBox.Count - 1 do
        begin
         //отправляем поочередно письма по всем адресам из списка одногрупников
         SendMsg(SResListBox.Items.Strings[i]);
         //визуализируем отправку
         MsgSStatusLabel.Caption := 'Отправка письма ' + inttostr(i+1) + ' из ' + inttostr(SResListBox.Count);
         MsgSendProgressBar.Position := MsgSendProgressBar.Position + 1;
        end;
       {//ждем пока компонент готовиться к работе
       repeat
       Application.ProcessMessages;
       until (smtp.State = smtpReady) or (smtp.State = smtpInternalReady);
       //закрытие почтовой сессии
       SMTP.Quit;
       //ждем пока компонент готовиться к работе
       repeat
       Application.ProcessMessages;
       until (smtp.State = smtpReady) or (smtp.State = smtpInternalReady);
       //отключение от сервера
       SMTP.Abort;}
      end else
      begin
       //выставляем позицию
       MsgSendProgressBar.Position := 0;
       MsgSendProgressBar.Max := 1;
       //если же адресат один, то отправляем письмо только ему
       SendMsg(ToComboBox.Text);
       //визуализируем отправку
       MsgSStatusLabel.Caption := 'Отправка письма 1 из 1';
       MsgSendProgressBar.Position := MsgSendProgressBar.Position + 1;
       {//ждем пока компонент готовиться к работе
       repeat
       Application.ProcessMessages;
       until (smtp.State = smtpReady) or (smtp.State = smtpInternalReady);
       //закрытие почтовой сессии
       SMTP.Quit;
       //ждем пока компонент готовиться к работе
       repeat
       Application.ProcessMessages;
       until (smtp.State = smtpReady) or (smtp.State = smtpInternalReady);
       //отключение от сервера
       SMTP.Abort;}
      end;
    end else
    begin
     //просим выбрать адресата
     ShowMessage('Поле "кому" не может быть пустым!');
    end;

    Процедура SendMsg вот:

    //коннектимся
    SMTP.Open;
    // получатель *+ копия
    BuildRcptList(addressee){можно добавить получателя копии письма+','+CopyTo.Text};
    Smtp.HdrTo := addressee;
    //прикрепленных файлов нет
    Smtp.EmailFiles := nil;
    // отправка почты
    try
     try
      //ждем пока компонент готовиться к работе
      repeat
      Application.ProcessMessages;
      until (smtp.State = smtpReady) or (smtp.State = smtpInternalReady);
      //отправляем письмо
      try
      SMTP.Mail;
      except on SMTPException do
       begin
        SMTP.Open;
        //ждем пока компонент готовиться к работе
        repeat
        Application.ProcessMessages;
        until (smtp.State = smtpReady) or (smtp.State = smtpInternalReady);
        SMTP.Mail;
       end;
      end;
      //добавляем адрес в список отправленных
      SendMails.Add(addressee);
     except on E:Exception do
      begin
       ShowMessage('Статус отправки: ERROR - '+E.Message);
       ShowMessage('Письмо не отправлено!');
      end;
     end;
    finally
     //ждем пока компонент готовиться к работе
     repeat
     Application.ProcessMessages;
     until (smtp.State = smtpReady) or (smtp.State = smtpInternalReady);
     //закрытие почтовой сессии
     SMTP.Quit;
     //ждем пока компонент готовиться к работе
     repeat
     Application.ProcessMessages;
     until (smtp.State = smtpReady) or (smtp.State = smtpInternalReady);
     //отключение от сервера
     SMTP.Abort;
    end;

    По идее должно работать... ведь даже тот же outlook может сначала накопить кучку писем для отправки, а потом их все отправить кому нужно, причем там и по 50 писем за раз уходит нормально...
  • Сергей М. © (27.08.09 08:34) [21]
    Непонятно, зачем для отправки каждого письма из подготовленного к отправке списка писем ты всякий раз открываешь новую SMTP-сессию ...
    Почему не оправить весь список в одной и той же сессии ?
  • belousov © (27.08.09 12:40) [22]
    Пробовал и в одной сессии, разницы нет! Все равно больше 8 писем не отправляется! Должно же быть решение...
  • Сергей М. © (27.08.09 13:39) [23]

    > больше 8 писем не отправляется


    Что, 9-е письмо прямо так и говорит "я не отправляюсь" ?

    И ты уж определись как-нибудь, то ли они у тебя не отправляются, то ли не доходят .. Разные ж две разницы)
  • belousov © (27.08.09 14:31) [24]
    Не доходят!
  • Сергей М. © (27.08.09 14:42) [25]
    А как ты обрабатываешь OnRequestDone и OnResponse ?
  • belousov © (27.08.09 15:18) [26]
    никак не обрабатываю... а как нужно?
  • Сергей М. © (27.08.09 15:25) [27]
    Да ну хотя бы в целях отладки посмотреть Msg в OnResponse и RqType,ErrorCode в OnRequestDone ..

    Полученная при этом инф-ция поможет тебе пролить свет на тайну "исчезновения" 9-го письам)
  • belousov © (27.08.09 15:34) [28]
    Спасибо, попробую) и ещё такой вопросик... отправленные с помощью ICS письма(которые дошли) попадают на mail.ru в папку "Сомнительные", если же использовать Indy, то приходят как и положено в папку "Входящие", но в Indy сколько я не мучался так и не смог добиться чтобы тело письма приходило нормальным текстом, а не иероглифами или же вопросиками(если не пытаться что либо делать с кодировкой). Вот интересно как бы на ICS сделать так, чтобы письма приходили в папку "Входящие", а не в "Сомнительные"?
  • Сергей М. © (27.08.09 15:48) [29]

    > отправленные с помощью ICS письма(которые дошли) попадают
    > на mail.ru в папку "Сомнительные"


    Значит ICS-клиент в отправляемых заголовках писем где-то как-то отходит от каких-то требований RFC 2822, а smtp-сервер на mail.ru, напротив, ожидает их соблюдения ... Или сервер расценивает твои письма как потенциальный спам или небезопасную корреспонденцию ..


    > чтобы тело письма приходило нормальным текстом


    Приходило куда ?
  • Сергей М. © (27.08.09 15:52) [30]

    > если не пытаться что либо делать с кодировкой


    А что-то мешает этим попыткам ?
  • belousov © (27.08.09 15:59) [31]

    > отходит от каких-то требований RFC 2822


    А как можно это узнать, чтобы в дальнейшем исправить?


    > посмотреть Msg в OnResponse и RqType,ErrorCode в OnRequestDone


    Кстати спасибо ещё раз уже посмотрел... оказалось, что там таймаут надо 1 минуту ставить после определенного количества писем...


    > Приходило куда ?


    На почту... С заголовком письма я там разобрался - все по русски нормально приходит, а вот сам текст(тело) письма отображается коряво. Пробовал и исходники исправлять как пишут на форумах и кодировать по разному, но как не старался текст письма все равно отображается иероглифами.
  • Сергей М. © (27.08.09 16:17) [32]

    > как можно это узнать, чтобы в дальнейшем исправить?
    >


    Достаточно сравнить заголовок и тело одного и того же письма, отправляемого ICS и попадающего в сомнительные и отправляемого любым иным клиентом, при котором письмо туда не попадает.


    > там таймаут надо 1 минуту ставить после определенного количества
    > писем


    А как же Аутлук ?
    Он тоже "посмотрел" ?)


    > На почту


    Что значит "на почту" ?


    > как не старался текст письма все равно отображается иероглифами


    http://pda.delphimaster.net/?id=1233223566&n=4
    http://pda.delphimaster.net/?id=1239719308&n=4
  • belousov © (27.08.09 16:32) [33]

    > сравнить заголовок и тело одного и того же письма


    попробую


    > А как же Аутлук ?
    > Он тоже "посмотрел" ?)


    не понял)


    > Что значит "на почту" ?


    e-mail(почтовый ящик)...)
  • Сергей М. © (27.08.09 16:45) [34]

    > не понял)
    >


    Вот и я не понял, где ты посмотрел про таймаут в 1 минуту)


    > e-mail(почтовый ящик)...)


    Пока ты не забрал почту из "ящика", рассуждать про "отображается коряво" бессмысленно .
    Вот я и спрашиваю, где ты наблюдаешь "корявость", в каком почтовом клиенте ? В самодельном ?
  • belousov © (28.08.09 13:20) [35]

    > Пока ты не забрал почту из "ящика", рассуждать про "отображается
    > коряво" бессмысленно .
    > Вот я и спрашиваю, где ты наблюдаешь "корявость", в каком
    > почтовом клиенте ? В самодельном ?


    Нет, когда захожу в почтовый ящик через сайт mail.ru


    > Вот и я не понял, где ты посмотрел про таймаут в 1 минуту)


    Сделал лог отправки письма:

    procedure TMainForm.SmtpRequestDone(Sender: TObject; RqType: TSmtpRequest;
     ErrorCode: Word);
    var s: string;
    begin
    case RqType of
     smtpConnect: Log.Add('connect');
     smtpHelo: Log.Add('helo');
     smtpMailFrom: Log.Add('mailfrom');
     smtpVrfy: Log.Add('vrfy');
     smtpRcptTo: Log.Add('rcptto');
     smtpData: Log.Add('data');
     smtpQuit: Log.Add('quit');
     smtpRset: Log.Add('rset');
     smtpOpen: Log.Add('open');
     smtpMail: Log.Add('mail');
     smtpEhlo: Log.Add('ehlo');
     smtpAuth: Log.Add('auth');
     smtpCustom: Log.Add('custom');
    end;
    s := inttostr(ErrorCode);
    Log.Add(s);
    Log.SaveToFile('log.txt');
    end;

    и

    procedure TMainForm.SmtpResponse(Sender: TObject; Msg: string);
    begin
    Log.Add(Msg);
    Log.SaveToFile('log.txt');
    end;

    Вот что получилось в логе:

    ....
    220 mail.ru ESMTP Fri, 28 Aug 2009 13:19:28 +0400
    250-mx38.mail.ru Hello smtp.mail.ru [80.240.220.103]
    250-SIZE 31457280
    250-8BITMIME
    250-AUTH PLAIN LOGIN
    250 PIPELINING
    334 VXNlcm5hbWU6
    334 UGFzc3dvcmQ6
    235 Authentication succeeded
    open
    0
    250 OK
    250 Accepted
    403 You have exceeded message sending limit, and i will not accept any messages from you within 1 minute
    500 unrecognized command
    mail
    500
    500 unrecognized command
    500 unrecognized command
    500 Too many unrecognized commands
    quit
    0
    ....
  • Сергей М. © (28.08.09 13:37) [36]

    > когда захожу в почтовый ящик через сайт mail.ru


    Отправляй в кодировке KOI8-R или Win1251, тогда проблем не будет.


    > 403 You have exceeded message sending limit, and i will
    > not accept any messages from you within 1 minute


    Поятно.
    mail.ru smtp-сервер справедливо подозревает тебя в распространении спама)
  • belousov © (28.08.09 14:12) [37]

    > Отправляй в кодировке KOI8-R или Win1251, тогда проблем
    > не будет.


    Да пробовал и ничего не получилось... может с опытом придет)

    ...и письма кстати приходят иногда в папку "Входящие", а иногда в сомнительные "Сомнительные" несмотря на то что и заголовок и тело у них одинаковые!
  • Сергей М. © (28.08.09 15:40) [38]

    > пробовал и ничего не получилось


    Значит не то или не так пробовал, оттого и не получилось


    > письма кстати приходят иногда в папку "Входящие", а иногда
    > в сомнительные "Сомнительные"


    Значит они заведомо не одинаковые
  • Данияр (21.08.10 23:48) [39]
    Здраствуйте , я новичок и хотел спросить , как можно отправить копю собщении ? Я исползую компоненты smtp и id message из Indy
 
Конференция "Сети" » Подскажите как отправить письмо используя сокеты? [D7, WinXP]
Есть новые Нет новых   [134436   +25][b:0][p:0.001]