Модераторы: Aliance, skyboy, MoLeX, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ожидание ответа функции fgets 
:(
    Опции темы
maykoff
Дата 9.1.2008, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 19.8.2006

Репутация: нет
Всего: нет



Код:
Код

$f = fopen("/dev/xxxx","a+");
fputs($f,"AT\r\n");
for(;!feof($f);)
{
    $str = fgets($f,8);
    echo "$str";
    if(preg_match("/OK\r\n/",$str)) break;
}
fclose($f);


/dev/xxxx - это компорт, на котором висит GSM-шлюз.
В консоли это выглядит так:

AT - запрос
OK - ответ

Проблема в том, что конца файла у $f, похоже , просто нет.
Прочитав всё что можно, на строке $str = fgets($f,8); зависает, ожидая дальнейшего вывода, которого нет, до выхода по условию цикла дело не доходит.

Как вариант - задать (сэмулировать) таймаут для функции, в которую поместить чтение из указателя.
Но как это сделать - пока не придумал.

Идею с отдельным исполняемым скриптом держу про запас.

Если у кого какие соображения на этот счёт будут - заранее благодарен .

P.S. Прошу не посылать на тему "Виснет скрипт на fgets" - смотрел - там эта проблема не решена, её просто обошли.

Мне именно нужно избежать (не допустить) зависания в случае нестандартного (непредвиденного ) ответа шлюза.

Это сообщение отредактировал(а) maykoff - 9.1.2008, 19:32
PM MAIL   Вверх
sTa1kEr
Дата 11.1.2008, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: нет
Всего: 146



Используйте stream_set_timeout(). Тогда по достижению заданного таймаута fgets() будет "отпускать" скрипт.
Код

$f = fopen("/dev/xxxx","a+");
stream_set_timeout($f, 5);
fputs($f,"AT\r\n");
for(;!feof($f);)
{
    $str = fgets($f,8);
    echo "$str";
    if(preg_match("/OK\r\n/",$str)) break;
}
fclose($f);

PM MAIL   Вверх
maykoff
Дата 12.1.2008, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 19.8.2006

Репутация: нет
Всего: нет



Не факт, что сработает, но спасибо, завтра попробую. Спасибо.

Нет ли способа проверит состояние открытого потока? В частности - проверить , все ли байты из него вычитаны или количество невычитанных байтов.

И ещё - подходит ли для этой задачи fopen ? Или есть более подходящие функции?


Это сообщение отредактировал(а) maykoff - 12.1.2008, 00:04
PM MAIL   Вверх
FractalizeR
Дата 12.1.2008, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 27.12.2007
Где: Россия/Москва

Репутация: нет
Всего: 4



www.php.net/stream_get_meta_data

Думаю, fopen подходит вполне

Это сообщение отредактировал(а) FractalizeR - 12.1.2008, 17:32


--------------------
Чтобы поблагодарить или наоборот поругать участника форума лучше пользоваться значками "+" и "-", изменяющими репутацию. Они находятся слева от поста под именем пользователя.
PM MAIL   Вверх
maykoff
Дата 12.1.2008, 23:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 19.8.2006

Репутация: нет
Всего: нет



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

Это сообщение отредактировал(а) maykoff - 12.1.2008, 23:14
PM MAIL   Вверх
FractalizeR
Дата 13.1.2008, 01:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 273
Регистрация: 27.12.2007
Где: Россия/Москва

Репутация: нет
Всего: 4



Я же говорю - вызвать stream_get_meta_data и посмотреть, сколько байт находится в буфере непрочитанных. Вы документацию по моей ссылке смотрели?

Это сообщение отредактировал(а) FractalizeR - 13.1.2008, 01:53


--------------------
Чтобы поблагодарить или наоборот поругать участника форума лучше пользоваться значками "+" и "-", изменяющими репутацию. Они находятся слева от поста под именем пользователя.
PM MAIL   Вверх
maykoff
Дата 13.1.2008, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 19.8.2006

Репутация: нет
Всего: нет



sTa1kEr, поюзал stream_set_timeout($f, 5); - как и ожидалось - не сработало. 
PM MAIL   Вверх
maykoff
Дата 13.1.2008, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 19.8.2006

Репутация: нет
Всего: нет



FractalizeR, смотрел.
Цитата

unread_bytes (int) - the number of bytes currently contained in the PHP's own internal buffer. 
Note: You shouldn't use this value in a script.

Вот код (sleep`ы убрал, чтоб не захламлять):
Код

$f = fopen(config::COMPORT,"a+");       //открываю компорт
print_r(stream_get_meta_data($f));     //смотрю состояние
fputs($f,"AT\r\n");                                  //подаю команду, типичный ответ - ОК
print_r(stream_get_meta_data($f));     //смотрю состояние
for($i=0,$z='';;$i++)                              //вычитываю все данные из потока
{
    $s = fgetc($f);                                   //посимвольно (байтами)
    $s = base_convert(ord($s),10,16);   //для отображения непечатных символов
    if(strlen($s) == 1) $s = "0$s";           //для красоты
    $z.= $s;
    echo $i." ".$s." $z\r\n";                     //вывожу
}


Вот вывод:
Код

Array
(
    [wrapper_type] => plainfile
    [stream_type] => STDIO
    [mode] => a+
    [unread_bytes] => 0
    [seekable] => 1
    [uri] => /dev/cuaa0
    [timed_out] =>
    [blocked] => 1
    [eof] =>
)
Array
(
    [wrapper_type] => plainfile
    [stream_type] => STDIO
    [mode] => a+
    [unread_bytes] => 0
    [seekable] => 1
    [uri] => /dev/cuaa0
    [timed_out] =>
    [blocked] => 1
    [eof] =>
)
0 41 41
1 54 4154
2 0d 41540d
3 0d 41540d0d
4 0a 41540d0d0a
5 4f 41540d0d0a4f
6 4b 41540d0d0a4f4b
7 0d 41540d0d0a4f4b0d
8 0a 41540d0d0a4f4b0d0a
9 f8 41540d0d0a4f4b0d0af8

Скрипт работу не закончил - завис.
Расшифровка вывода - примерно 
AT
OK

f8 - левый какой-то байт, он присутствует в каждом ответе один раз (иногда - на разных позициях, но прогнозируемо)

Как видно - Количество байт в сокете не отображено, да и не рекомендуется этот параметр к использованию.

Если есть соображения по этому поводу - с удовольствием выслушаю smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Сеть | Следующая тема »


 




[ Время генерации скрипта: 0.0775 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.