fsockopen, fgets виснет

Qwerty

Новичок
fsockopen, fgets виснет

Работаю из php с ftp через сокеты. Нужно считывать то, что отвечает ftp сервер. Так вот, при достижении конца "файла" функция fgets виснет. Определить же конец файла не получается (условие проходит).
PHP:
$fp=@fsockopen($host,21,&$errnr,&$errstr,15); 
fputs($fp,"USER $login\r\n"); 
fputs($fp,"PASS $pass\r\n"); 
while (!feof($fp)) { 
  $line=fgets($fp,128); // тут виснет 
  echo "$line<br />"; 
}
При этом, если делаю http запрос, то при выходе за пределы "файла" fgets просто выдает false, как и следовало ожидать.
PHP:
$fp=@fsockopen($host,80,&$errnr,&$errstr,15); 
fputs($fp,"GET $path HTTP/1.0\r\n\r\n");
--
Версия PHP 4.3.10
 

SiMM

Новичок
Не надо сравнивать божий дар с яичницей. HTTP - послал запрос, получил отклик - свободен. FTP - соединение может держаться сколь угодно долго, до тех пор, пока оно не будет разорвано клиентом. Отсюда вывод - читать спецификацию по FTP. Типичный сеанс:
cmd> telnet localhost 21

<= 220 Serv-U FTP Server v6.1 for WinSock ready...
=> username
<= 331 User name okay, need password.
=> password
<= 230 User logged in, proceed.
=> следующий запрос пользователя
...
=> QUIT
сеанс окончен
 

Qwerty

Новичок
Да, я эти вещи, в общем-то, знаю.
Ситуация возникла вот откуда: некоторые сервера отдают при подключении к ним несколько строк приветствия 220. Таким, образом, я не могу знать точно, сколько строк читать.
Далее: что, если я отправлю команду, а сервер по какой-то причине не ответит? Получим ситуацию с зависшим fgets, чего очень хотелось бы избежать.
Вообще, само зависание функции мне кажется очень странным, она должна false выдавать...
 

440hz

php.ru
Автор оригинала: Qwerty
Вообще, само зависание функции мне кажется очень странным, она должна false выдавать...
почему false - сокет же открыт. ждем новых данных ...
 

SiMM

Новичок
> Вообще, само зависание функции мне кажется очень странным, она должна false выдавать...
Так ошибки-то нет. Функция просто ждёт данные до символа завершения строки. Что касается вашего случая - ничто же не мешает вам логиниться и пропускать все строки приветствия до появления 331 (или кода отклика, отличного от 220).
 

Qwerty

Новичок
SiMM:
пропускать все строки приветствия до появления 331 (или кода отклика, отличного от 220)
Да, я думал сделать так. Но вопрос в том, что на какую-нибудь команду сервер ведь тоже может ответить несколькими строчками? Или только приветствие может быть в несколько строк?
Тогда проблема практически исчезает.
За stream_set_timeout спасибо.
 

SiMM

Новичок
> Но вопрос в том, что на какую-нибудь команду сервер ведь тоже может ответить несколькими строчками?
А что по этому поводу думает RFC? ;)
 

Qwerty

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