Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: fsockopen и кодировка

 PHP.SU

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


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

> Без описания
john smith
Отправлено: 08 Мая, 2010 - 21:55:10
Post Id


Новичок


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


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




Есть скрипт, точнее кусок от него:
PHP:
скопировать код в буфер обмена
  1. $server="91.211.116.10"; //сдесь ip сервера
  2. $fp = fsockopen ("udp://".$server,27017, $errno, $errstr);
  3. if (!$fp) {
  4. echo "ERROR: $errno - $errstr<br>\n";
  5. } else {
  6. fwrite($fp,"\xFF\xFF\xFF\xFFTSource Engine Query\0");
  7. $st=fread($fp,1);
  8. $r=$r["unread_bytes"];
  9. $st.=fread($fp,$r);

Суть его работы - соединяется с сервером CS, получает инфу о нем, возвращает.

Скрипт запускаю на локалке и на хостинге. Результат разный.
На локалке:
string(117) "����m127.0.0.1:27016\0NoN-STOP Server\0aim_aggro\0cstrike\0Counter-Strike\0/dw\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
48

На хостинге:
string(98) "����m127.0.0.1:27016�NoN-STOP Server�aim_aggro�cstrike�Counter-Strike�/dw��������������"
14

Кодировка страницу utf.
Переставлял сервер уже - тут заметил одну фишку. На апаче 2.0 - работает, на 2.2 - уже вот показывает разницу в этой длине строки.
Поскольку на сайте http://php-myadmin[dot]ru/learning/i[dot][dot][dot]ment-apache[dot]html нашел толковое описание установки и настройки - оставил именно более позднюю версию (на которой работает некорректно). ПОлучается так, что на устаревшем не сконфигурированном апаче отображается нормально, а на настроеном как по вышеуказанному мануалу - фигня происходит. В чем загвоздка тут? Хотелось бы привести к какомуто однообразию, чтоб можно было распарсить строку и не париться, будет ли оно работать на 2.0 апаче, или на 2.2.
Гдето в настройкахх проблема (пхп + апач), но уже все перерыл - не нашел.
 
 Top
valenok Модератор
Отправлено: 09 Мая, 2010 - 01:07:40
Post Id



Здесь могла бы быть ваша реклама


Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006  
Откуда: Israel


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




http://il2.php.net/manual/en/fun...et-meta-data.php
Прочти внимательно что написанно в выделенном белом квадратике под unread_bytes.


-----
Truly yours, Sasha.
 
My status
 Top
john smith
Отправлено: 09 Мая, 2010 - 01:37:22
Post Id


Новичок


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


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




valenok пишет:
http://il2.php.net/manual/en/fun...et-meta-data.php
Прочти внимательно что написанно в выделенном белом квадратике под unread_bytes.

Я не собираюсь целиком юзать этот кусок скрипта, мне для пробы.
Одно дело если б вообще не работало - тогда понятно что ошибка в коде, а так работает, но результат разный на локалке и хостинге. А тут дело не в unread_bytes. В настройках, видимо, но не имею понятия где именно.
 
 Top
valenok Модератор
Отправлено: 09 Мая, 2010 - 12:47:51
Post Id



Здесь могла бы быть ваша реклама


Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006  
Откуда: Israel


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




Это размер внутреннего буфера php и работать с ним не нужно, о чем достаточно ясно выразились в документации. Придумайте другой путь выполнения того, что вам надо, а потом будем смотреть, почему оно не работает.

Если вам будет проще понять как "Это баг в php - не мучайтесь с найстройками" - пусть будет так.


-----
Truly yours, Sasha.
 
My status
 Top
JustUserR
Отправлено: 09 Мая, 2010 - 15:26:19
Post Id



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


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


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




john smith Может следует попробовать сменить локаль PHP-скрипта с помощью setlocale - или же сделать соответствующее преобразование кодировки с помощью iconv Кроме того в PHP было изменено поведение по отношению к символу \0 - он может преобразовываться в \\0


-----
Сделать можно все что угодно - нужно только старание, терпение и хороший поисковик Улыбка
Безлимитный web-хостинг от 15 рублей за 40 МБ дискового пространства - http://ihost[dot]oks71[dot]ru/
 
 Top
john smith
Отправлено: 09 Мая, 2010 - 19:32:33
Post Id


Новичок


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


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




valenok
Я смотрел много таких скриптов (мониторинг сервера игрового). Во всех использовали такой подход при считывании данных из сокета. Идея не моя, поэтому не буду говорить что это хорошо. СПасибо за ман, буду думать как по-другому сделать.

JustUserR
Локаль менял кстати.
А дело все в одной дурацкой штуке))) Помог человек, который подобный скрипт писал. Данные то приходят извне, а у меня настройка на magic_quotes, и оно экранирует все спец символы что в строке. Потому и разница в длине.
Спасибо за советы.
 
 Top
valenok Модератор
Отправлено: 09 Мая, 2010 - 21:24:13
Post Id



Здесь могла бы быть ваша реклама


Покинул форум
Сообщений всего: 4574
Дата рег-ции: Июль 2006  
Откуда: Israel


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




Для чтения всех данных из сокета используется мега конструкиця
while(!feof($stream)) $st .= fread($stream, 1024);

В какой она там кодировке, и какие там вообще могут быть символы - не ясно.
Не пугайтесь если они там отображаются каракулями в браузере.
Там вполне могут быть символы из первой 20-ки ascii и на их отображение надеяться нет смысла.

Между прочим символ \0 означает конец строки.
Только в одном случае оно вывело как слэш и 0, а в другом вывело как положено.
На самом деле у тебя оба результата выглядят достаточно идентично,
даже если оценить это визуально по началу сложно.

Можешь продолжать работать с этими данными дальше, как планировал.
Там нет никаких особых ошибок и вывод в обоих случаях фактически идентичен.


-----
Truly yours, Sasha.
 
My status
 Top
JustUserR
Отправлено: 10 Мая, 2010 - 01:27:51
Post Id



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


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


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




john smith пишет:
JustUserR Локаль менял кстати.
А дело все в одной дурацкой штуке))) Помог человек, который подобный скрипт писал. Данные то приходят извне, а у меня настройка на magic_quotes, и оно экранирует все спец символы что в строке. Потому и разница в длине.
Спасибо за советы.
Пожалуйста! В принципе выше я как раз сделал подобное предположение - а именно PHP-скрипт определенным образом экранирует часть спецсимволов (В вашем случае нулевой символ \0 преобразовывался в \\0 )
valenok пишет:
В какой она там кодировке, и какие там вообще могут быть символы - не ясно.
Не пугайтесь если они там отображаются каракулями в браузере.
Там вполне могут быть символы из первой 20-ки ascii и на их отображение надеяться нет смысла.
С одной стороны двоичные данные они на то и есть что не впринципе не имеют никакой кодировке и выводить их в текстовом виде не имеет вида - но с другой стороны в PHP они хранятся как обычные строки и надо следить на тем чтобы при их пересылке и обработки не происходило преобразования кодировок


-----
Сделать можно все что угодно - нужно только старание, терпение и хороший поисковик Улыбка
Безлимитный web-хостинг от 15 рублей за 40 МБ дискового пространства - http://ihost[dot]oks71[dot]ru/
 
 Top
john smith
Отправлено: 10 Мая, 2010 - 22:55:02
Post Id


Новичок


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


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




У меня еще вопрос про сокеты появился. Судя из моего кода в первом посте, то в случаее неудачной попытки подключения в $fp попадает false и должно вывестись echo "ERROR: $errno - $errstr<br>\n";. Но почемуто fsockopen не возвращает false, а "делает вид" что все хорошо (если айпи ошибочный) и передает все на

и уже freadвызывает свою ошибку. ВОпрос - почему не срабатывает

(Отредактировано автором: 10 Мая, 2010 - 22:59:38)

 
 Top
JustUserR
Отправлено: 11 Мая, 2010 - 10:31:17
Post Id



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


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


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




john smith пишет:
ВОпрос - почему не срабатывает
На самом деле в фукнции fsockopen для определения произошедней ошибки используется 3 аргумент функции который передается по ссылке - и для определения факта ошибки вам надо провекрять именно его ненулевое значение - в вашем случае то переменная $errno


-----
Сделать можно все что угодно - нужно только старание, терпение и хороший поисковик Улыбка
Безлимитный web-хостинг от 15 рублей за 40 МБ дискового пространства - http://ihost[dot]oks71[dot]ru/
 
 Top
john smith
Отправлено: 11 Мая, 2010 - 15:38:52
Post Id


Новичок


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


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




JustUserR
И вправду так, нашел в мануале это "исключение".
Цитата:
UDP sockets will sometimes appear to have opened without an error, even if the remote host is unreachable.

Я думал обрабатывать уже fwrite или fread, они то возвращают стабильно false если че. Но это по-индусски Улыбка

UPD.
Все же что имеем. Посколько fsockopen не всегда возвращает false (и не всегда в $errno чтото оказывается) то сделал проверку на то, получилось ли прочитать чтото. Уже исходя с этого генерировать исключение.
PHP:
скопировать код в буфер обмена
  1. function cstrike_monitor($ip = 0, $port = 0)
  2. {
  3.         $ret = array();
  4.         $fp = fsockopen ('udp://'.$ip, $port, $errno, $errstr);
  5.         if (!$fp)
  6.         {
  7.                 echo "ERROR: $errno - $errstr<br>\n";
  8.                 return $ret['status'] = 'off';
  9.         }
  10.         else
  11.         {
  12.                 fwrite($fp, "\xFF\xFF\xFF\xFFTSource Engine Query\0");
  13.                 stream_set_timeout($fp, 0, 400000);
  14.                 $st = fread($fp, 4);
  15.                 if(empty($st))
  16.                 {
  17.                         return $ret = array('status' => 'off');
  18.                 }
  19.                 else
  20.                 {      

(Отредактировано автором: 11 Мая, 2010 - 16:32:16)

 
 Top
JustUserR
Отправлено: 12 Мая, 2010 - 09:33:53
Post Id



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


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


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




john smith пишет:
JustUserR
И вправду так, нашел в мануале это "исключение".
Цитата:
UDP sockets will sometimes appear to have opened without an error, even if the remote host is unreachable.
Понимаете на самом деле это весьма не исключитпельное поведение ввиду особенностей протокола UDP - ведь он не гарантирует доставку датаграммы и передача осуществляется в общем случае без обратного пакета - таким образом недоступность порта UDP можно определить только если послать на него данные и по IGMP будет прислано сообщение о том что доставить не удалось - если соответствующая доставка IGMP отключена или блокируется firewall-ом то узанть не получится вообще никак - разве только на основании того факта что удаленный сервер ничего не присывает в ответ некоторое время
Поэтому факт возникновения исключения будет только в том случае когда по IGMP сразу пришло сообщение о недоступности данног UPD-порта


-----
Сделать можно все что угодно - нужно только старание, терпение и хороший поисковик Улыбка
Безлимитный web-хостинг от 15 рублей за 40 МБ дискового пространства - http://ihost[dot]oks71[dot]ru/
 
 Top
alex baxter
Отправлено: 13 Мая, 2010 - 01:56:04
Post Id


Новичок


Покинул форум
Сообщений всего: 1
Дата рег-ции: Май 2010  


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




Привожу мою модификацию этого кода.
Особо отмечу проверку внутри цикла while на то не закрылся ли сокет в процессе получения данных и отчистке буфера (браузер "подвисал" со старыми значениями в буфере при нескольких обновлениях страницы)

Спойлер (Отобразить)

(Отредактировано автором: 13 Мая, 2010 - 03:00:18)

 
 Top
JustUserR
Отправлено: 13 Мая, 2010 - 12:58:57
Post Id



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


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


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




alex baxter пишет:
Особо отмечу проверку внутри цикла while на то не закрылся ли сокет в процессе получения данных и отчистке буфера (браузер "подвисал" со старыми значениями в буфере при нескольких обновлениях страницы)
Проверка работоспособности сокета для отправки данных это дело правильное - а вот насчет очистки буфера можно быбол бы сделать статическую HTML-страницу и воспользоваться на ней JS-скритом который бы помогал загружать новые данные с web-сервера без кеширования


-----
Сделать можно все что угодно - нужно только старание, терпение и хороший поисковик Улыбка
Безлимитный web-хостинг от 15 рублей за 40 МБ дискового пространства - http://ihost[dot]oks71[dot]ru/
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Программирование на PHP »


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



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

 
Powered by ExBB FM 1.0 RC1. InvisionExBB