PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: Проблема с оправкой почты по SMTP с помощью сокетов на mail.ru
cod
Отправлено: 26 Июля, 2011 - 18:44:36
Post Id


Новичок


Покинул форум
Сообщений всего: 6
Дата рег-ции: Июль 2011  


Помог: 0 раз(а)




Хочу совсем немного. Всего лишь реализовать отправку почты с сайта. Делаю для этого функцию. В принципе письма уходят.
Но вот как я этого добился:

PHP:
скопировать код в буфер обмена
  1.  
  2. $fp= fsockopen('smtp.mail.ru', 25);
  3.  if ($fp){
  4.        
  5.     $in = fgets($fp, 256); //смотрим что нам ответил сервер
  6.      echo "<--".$in."<br>"; //выводим это
  7.  
  8.         $sent = fputs($fp, "EHLO mail\r\n"); //посылаем ему команду
  9.         if ($sent) echo "-->EHLO mail(".$sent.")<br>"; //выводим в браузер информацию о том что отправили
  10.  
  11.     $in = fgets($fp, 256)."<br>";
  12.     echo "<--".$in."<br>";
  13.  
  14. //Метка 1!
  15.         $in = fgets($fp, 256)."<br>";
  16.         echo "<--".$in."<br>";
  17.         $in = fgets($fp, 256)."<br>";
  18.         echo "<--".$in."<br>";
  19.         $in = fgets($fp, 256)."<br>";
  20.         echo "<--".$in."<br>";
  21.         $in = fgets($fp, 256)."<br>";
  22.         echo "<--".$in."<br>";
  23.  
  24.         $sent = fputs($fp, "AUTH LOGIN\r\n");
  25.         if ($sent) echo "-->AUTH LOGIN (".$sent.")<br>";
  26.         $in = fgets($fp, 256);
  27.         echo "<--".$in."<br>";
  28.  
  29.         $sent = fputs($fp, base64_encode('логин для авторизации')."\r\n");
  30.         if ($sent) echo "-->".base64_encode('логин')."(".$sent.")<br>";
  31.         $in = fgets($fp, 256);
  32.         echo "<--".$in."<br>";
  33.  
  34.         $sent = fputs($fp, base64_encode('пароль')."\r\n");
  35.         if ($sent) echo "-->".base64_encode('пароль')."(".$sent.")<br>";
  36.         $in = fgets($fp, 256);
  37.         echo "<--".$in."<br>";
  38.  
  39.         $sent = fputs($fp, "MAIL FROM: senderlogs@mail.ru\r\n");
  40.         if ($sent) echo "-->MAIL FROM senderlogs@mail.ru (".$sent.")<br>";
  41.         $in = fgets($fp, 256);
  42.         echo "<--".$in."<br>";
  43.  
  44.         $sent = fputs($fp, "RCPT TO: кому\r\n");
  45.         if ($sent) echo "-->RCPT TO кому (".$sent.")<br>";
  46.         $in = fgets($fp, 256);
  47.         echo "<--".$in."";
  48.  
  49.  
  50.         $sent = fputs($fp, "DATA\r\n");
  51.         if ($sent) echo "-->DATA (".$sent.")<br>";
  52.         $in = fgets($fp, 256);
  53.         echo "<--".$in."<br>";
  54.  
  55.         $sent = fputs($fp, $SEND."\r\n.\r\n"); //gпеременная $SEND сформирвана заранее
  56.         if ($sent) echo "-->тело письма (".$sent.")<br>";
  57.  
  58.         $in = fgets($fp, 256);
  59.         echo "<--".$in."<br>";
  60.  
  61.         $sent = fputs($fp, "QUIT\r\n");
  62.         if ($sent) echo "-->QUIT (".$sent.")<br>";
  63.  
  64.  


В браузер это выводит следующее

"<--220 smtp3.mail.ru ESMTP ready
-->EHLO mail(11)
<--250-smtp3.mail.ru

<--250-SIZE 31457280

<--250-8BITMIME

<--250-AUTH PLAIN LOGIN

<--250 STARTTLS

-->AUTH LOGIN (12)
<--334 VXNlcm5hbWU6
-->*************(26)
<--334 UGFzc3dvcmQ6
-->*************(14)
<--235 Authentication succeeded
-->MAIL FROM ######@mail.ru (31)
<--250 OK
-->RCPT TO ########@mail.ru (32)
<--250 Accepted -->DATA (6)
<--354 Enter message, ending with "." on a line by itself
-->тело письма (356)
<--250 OK id=1QljVS-0008U6-00
-->QUIT (6)"



алгоритм такой сначала пишем в сокет команду fputs(), выводим что написали, затем читаем ответ fgets() и выводим его на экран.

Не устраивает меня вот, что.
Там где у меня "метка 1" видно что при таком подходе необходимо выполнять fgets() ровно столько раз сколько строк в ответе от сервера. - линейный алгоритм получается Хм
Да, можно использовать feof() чтобы просто прочитать до конца НО! (вот мы и добрались до главного) если считать последний символ из сокета, или лучше сказать выполнить fgets() когда уже всё прочитано, то отправка прерывается и дальше не идёт, а в логах апача появляется запись
"PHP Fatal error: Maximum execution time of 30 seconds exceeded in C:\\Apache2.2\\htdocs\\localhost\\www\\smtp_send.php on line 94".

Вопрос такой, как сделать функцию, которая бы посылала команды получала ответы сервера и выводила их на экран?

Ой не знаю, надеюсь ситуацию понятно описал.


P.S> Ещё вот, возможно кто-то знает как можно узнать размер сообщений в сокете, подобно размеру файла, получаемому через filesize()? Это помогло бы узнать сколько можно считать.
Понимаю что возможо слегка глупо пишу, но я, при написании скрипта, представляю сокет как файл в который поочерёдно пишут клиент и сервер, где клиент это скрипт.

(Отредактировано автором: 26 Июля, 2011 - 19:09:47)

 
 Top
Мелкий Супермодератор
Отправлено: 26 Июля, 2011 - 20:06:58
Post Id



Активный участник


Покинул форум
Сообщений всего: 11884
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 614 раз(а)




0) mail
1) feof из сокета сработает в одном случае - соединение закрыто. Для сеансового протокола, как SMTP, это категорически не подходит. Но отлично подойдёт для HTTP, работающего по схеме: получил запрос, отправил ответ, закрыл соединение.
2) узнать, сколько данных придёт - невозможно.
3)
cod пишет:
представляю сокет как файл в который поочерёдно пишут клиент и сервер

Могут писать одновременно.
4) если хотите разобраться - смотрите в сторону неблокирующих сокетов


-----
PostgreSQL DBA
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 1 (гостей: 1, зарегистрированных: 0)
« Вопросы новичков »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB