не отправляется email при сокетном соединении

Alexandre

PHPПенсионер
не отправляется email при сокетном соединении

email через телнет отправляется.
PHP:
function xSend($host, $port, $to,$subject,$headers,$message)
{
 $from="[email protected]";


  $connection = fsockopen ($host, $port, &$errno, &$errstr, 1);
  if (!$connection)
   {
   die (" connection to $host failed  $errstr \n");
   return false;
   }
  $res=fgets($connection,256);
  print $res."\n";

  fputs($connection, "HELO \n");

  set_socket_blocking($connection, true);
  $res=fgets($connection,1);
    print $res;
    print_r (socket_get_status($connection)) ;


  fputs($connection, "MAIL FROM: $from\n");
  $res=fgets($connection,1);
    print $res;
    print_r (socket_get_status($connection)) ;

  fputs($connection, "RCPT TO: $to\n");
  $res=fgets($connection,1);
    print $res;

  fputs($connection, "DATA\n");
  $res=fgets($connection,1);
    print $res;

  fputs($connection, "To: $to\nFrom: $from\nSubject: $subject\n$headers\n\n$message\n.\n");
  $res=fgets($connection,1);
    print $res;

  fputs($connection,"QUIT\n");
  $res=fgets($connection,1);
    print $res;

  return true;
}
коннекция с смтп открывается а дальше
Код:
220 sendout-h Microsoft ESMTP MAIL Service, Version: 6.0.3790.0 ready at  Wed, 23 Aug 2006 18:58:17 +0400
если после каждого fputs($connection, "...\n"); $res=fgets($connection,1); выдает
Код:
Array
(
    [stream_type] => socket
    [unread_bytes] => 0
    [timed_out] =>
    [blocked] => 1
    [eof] =>
)
пытался ставить set_socket_blocking($connection, false); но нет изменений.
вообще-то после каждого fputs($connection,"..."); я должен что-то прочитать fgets
если я вместо чтения 1 символа ставлю 256, то скрипт просто виснет.
 

Popoff

popoff.donetsk.ua
Alexandre
1. Концы строк следует всегда писать как "\r\n". Об этом написано в RFC. Хотя, там также сказано, что некоторые (именно некоторые, а не все) сервера могут (именно могут, а не обязаны) правильно работать с "\r".

2. Считывать следует не по одному символу а сразу весь ответ.

3. Следующую команду следует посылать только проанализировав ответ и убедившись, что ответ правильный.

4. Ответ может состоять более чем из одной строки. Считывать следует все строки ответа. Как определить, сколько строк в ответе - описано в соответствующем RFC.

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

А почему ты не воспользуешься одной из готовых библиотек?

-~{}~ 26.08.06 01:47:

Да, ещё $message нужно обрабатывать перед отправкой: во-первых, чтобы в нём не было слишком длинных строк (для этого используется, к примеру, quoted-printable) и чтобы не было строк, в которых в самом начале стоит точка - первые точки в строках следует дублировать.
 

Alexandre

PHPПенсионер
2. Считывать следует не по одному символу а сразу весь ответ.
я считывал весь ответ (был пустым), но идея взята из примера (пользовательские дополнения ) на php.net
А почему ты не воспользуешься одной из готовых библиотек?
например???

Popoff спасипбо за советы.

-~{}~ 28.08.06 16:14:

Да, ещё $message нужно обрабатывать перед отправкой: во-первых, чтобы в нём не было слишком длинных строк (для этого используется, к примеру, quoted-printable) и чтобы не было строк, в которых в самом начале стоит точка - первые точки в строках следует дублировать.
я посмотрел, на attached файлы ограничение на длинну строк не распространяется.

я отправляю HTML письма, что-то с кодировкой, хотя <MATA> выставляю.
 

Popoff

popoff.donetsk.ua
Alexandre
Можешь скачать мой http://popoff.donetsk.ua/light - там есть файлик mail.smtp.php с уже реализованным, отлаженным и функционирующим с 2001 года протоколом, включающим, кроме всего прочего, смтп-аутентификацию. Файл mail.php тебе тоже может быть полезен - там функция _mail_body() для генерации тела почтового сообщения и функции ограничения нагрузки на сервер. Я, правда, не уверен насчёт прикрепления файлов - лет пять назад эту функцию тестировал и после этого ни разу не использовал, могло за это время что-то испортиться.

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

Кодировку следует указывать в заголовке Сontent-Type, как это сделано в моей библиотеке. Заголовки <meta> можно опустить - в большинстве случаев, тем более при отображении через веб-интерфейс, эти заголовки игнорируются.
 
Сверху