Чтение из сокета без таймаута

Фанат

oncle terrible
Команда форума
Что-то я туплю.
Банальная задача - пишу на деревню в яндекс ручками.
Хочу отследить момент, когда SMTP уже мне ответил и можно писать дальше.
если тупо вайл(фгетс), то оно ждёт таймаута.
stream_get_contents - тоже.

тупое
PHP:
  fputs($handle, "EHLO $mydomain\r\n");
  fgets($handle);
не работает, поскольку на EHLO яндекс выплёвывает кучу строк, и последующие фгетсы радостно дочитывают их, а не актуальные ответы на последующие запросы.

есть какой-то короткий вариант перестать читать, когда больше ничего не осталось?
или только вручную разбирать конкретные ответы?
 

Фанат

oncle terrible
Команда форума
Судя по всему, вопрос тупой, и узнать никак нельзя.
так то только по конкретным кодам, ага
 

Фанат

oncle terrible
Команда форума
PHP:
do{$str = fgets($handle)} while($str[3] != ' ');
Не знаю, насколько оно канонично, но работает без проверки конкретных кодов.
 

fixxxer

К.О.
Партнер клуба
да какой селект :) вопрос то не в этом вообще

если строка ответа с данным кодом не последняя, она в виде ^\d+-
если последняя, то ^\d+\s

последовательность нескольких ответов может быть, насколько я понимаю, только после сообщений об ошибках (40х и 50х) - так после них обычно уже все ясно и можно соединение закрывать

хотя я возможно не знаю тонкостей протокола :)
 

Фанат

oncle terrible
Команда форума
Ну я, собственно, на этот вопрос отвечал :)
Я так понял - эта штука скажет, что в сокете появились данные? Но мне надо наоборот, что больше данных нет.
а это-то она предсказать не может.

fixxxer
Ну, у меня вырожденный случай этого выражения :)
Жаль только, что надо писать его два раза - один раз после коннекта, и второй - в цикле.
В итоге получилось

PHP:
  $body    .= "$headers\r\n";
  $body    .= "\r\n";
  $body    .= "$content\r\n";
  $body    .= ".\r\n";

  $comm     = array (
			"EHLO $mydomain\r\n",
			"AUTH LOGIN\r\n",
			base64_encode($username)."\r\n",
			base64_encode($password)."\r\n",
			"MAIL FROM:<$sender>\r\n",
			"RCPT TO:<$recipient>\r\n", 
			"DATA\r\n", 
 			$body,
			"QUIT\r\n",
		);

  $handle = fsockopen($server,$port); 
  if (!$handle) {
    return;
  }
  stream_set_timeout($handle, 1);
  do {$str = fgets($handle);} while($str[3] != ' ');

  foreach ($comm as $line) {
    fputs($handle, $line); 
    do {$str = fgets($handle);} while($str[3] != ' ');
  }
}
Хотя, наверное, надо предусмотреть ситуацию, когда сокет ничего не вернулл, а вылетел по таймауту
 

Фанат

oncle terrible
Команда форума
Надо, чо. У меня и класса-то пока нету :)
А надо писать.
публичный метод для отправки, пара приватных для кодирования и два драйвера - системный мейл и вот это поделие.
Блин, сходил, называется, за хлебушком - сел регистрацию к древней гостевухе дописать :)
 

Gremboloid

инженера Гр...
Хотя, наверное, надо предусмотреть ситуацию, когда сокет ничего не вернулл, а вылетел по таймауту
когда писал опрос почтовых серверов, для решения этого вопроса пришлось к stream_set_timeout еще добавлять
PHP:
stream_set_blocking($handle, 1);
 

Фанат

oncle terrible
Команда форума
Gremboloid
интересно. А можешь описать ситуацию, когда это нужно?
 

Gremboloid

инженера Гр...
чтобы избавиться от циклов
PHP:
do {$str = fgets($handle);} while($str[3] != ' ');
 
Сверху