О сокетах и не только -------- for grigori

WAS71

Новичок
О сокетах и не только -------- for grigori

хотел пообщаться с grigori - который помог закрыть тему - и не помог решить проблему

и не стал бы я сюда писать если бы не прочитал кучу доки,

и может у вас сокеты открываются но у меня они именно создаются

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind ($socket, $address, $port);
socket_listen($socket, $max_clients);

и не в сокетах собственно дела, а в принципе - как сделать т.к. весь процесс обработки висит в вечном цикле

while(TRUE)
{
$read[0] = $socket;
................................
................................
................................
}

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

dimagolov

Новичок
тебе надо создавать отдельный процесс, чтобы не "останавливать дальнейшее выполнение".

только не совсем уверен в том, что ты правильно понимаешь что делаешь и зачем. расскажи, зачем тебе слушать порт?

вообще поиском, по socket_create, много интересного найдешь.
 

WAS71

Новичок
Устройство отсылает стандартный запрос на сервер, типа
GET http://82.47.200.5/imei.php?imei=353358013229955
передаю ИМЕЙ если он есть в базе - запускаю процедуру/модуль/скрипт - (незнаю как лучше звучит) в котором описано создание сокета, т.е. создаю сокет - по которому потом будет идти обмен данными, и так для каждого подключаемого устройства
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
>хотел пообщаться с grigori
ну здравствуй! Как тебя зовут? Я Гриша :)
Как поживаешь?
Ты какое ьудешь - светлое или темное?
Я - темное, как-раз в холодильнике остывает!

Ты уж прости, я перенесу в офтопик, чтоб не мешать людям программирование обсуждать, пока мы тут с тобой познакомимся.

У вас уже жарко? У нас уже тополинный пух и кондиционер.

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

-~{}~ 02.06.09 17:30:

Да, что касается сокетов.
Че ж ты детали сразу не написал? Это ж главное.

Все пишут тут вопросы конкретные, с примерами.
А начинать надо с цели, с описания задачи.
Я не придираюсь - глянь правила форума.

Впрочем, dimagolov уже и ответил все, что надо.

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

Ну так че, как ваша погода?
 

WAS71

Новичок
Привет, я Василий
я рад что теперь у тебя есть колонки, и пиво в холодильнике....
но собственно хотелось пообщаться по поводу программирования, выкинул ту часть которая пишет в базу, дабы не загромождать исходник

PHP:
function New_Socket() // Создание нового сокета
{
error_reporting(1);
ini_set('display_errors', '1');

// Set the ip and port we will listen on
//$address = 'localhost';
$port = 10000;
$max_clients = 10;

$fd = fopen('Socket_Data.txt', "a+");

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind ($socket, $address, $port);
socket_listen($socket, $max_clients);

$clients = array('0' => array('socket' => $socket));
while(TRUE)
 {
  $read[0] = $socket;
  for($i=1; $i<count($clients)+1; ++$i)
   {
    if($clients[$i] != NULL)
     {
      $read[$i+1] = $clients[$i]['socket'];
     }
   }

  $ready = socket_select($read, $write = NULL, $except = NULL, $tv_sec = NULL);
  if(in_array($socket, $read))
   {
    for($i=1; $i < $max_clients+1; ++$i)
     {
      if(!isset($clients[$i]))
       {
        $clients[$i]['socket'] = socket_accept($socket);
        socket_getpeername($clients[$i]['socket'],$ip);
        $clients[$i]['ipaddy'] = $ip;
        break;
       }
      elseif($i == $max_clients - 1)
       {
        echo 'To many Clients connected!'."\r\n";
       }

      if($ready < 1)
       {
        continue;
       }
     }
   }

  for($i=1; $i<$max_clients+1; ++$i)
   {
    if(in_array($clients[$i]['socket'], $read))
     {
      $data = @socket_read($clients[$i]['socket'], 1024, PHP_BINARY_READ);

      if($data === FALSE)
       {
        unset($clients[$i]);
        echo 'Client disconnected!',"\r\n";
        continue;
       }
//***********************************************************************************************************************//
      fwrite($fd,$data.chr(13));

      $msg='Rec_OK'.chr(13).chr(10); 
      socket_write($clients[$i]['socket'], $msg, strlen($msg));
      continue;
//***********************************************************************************************************************//
         }
        break;
       }
      }
    }
 }

fclose($fd);

}
-~{}~ 02.06.09 18:43:

.....все форматирование сломалось
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Понимаешь, веб-скрипты в принципе должны быстро обработать запрос, собрать веб-страницу и вернуть пользователю.
У веб-сервера процессов немного и все должны отстреливаться быстро.
А обмен данными, открытие сокетов и т.п. - процесс длительный.

Тебе нужен отдельный демон, который откроет сокет - он будет ждать, когда с ним соединятся, будет общаться с устройством сколько надо.
А веб-сервер - это другое. Из-под веб-сервера ты ту никак соединение с устройством не обработаешь.

Задачка не простая, конечно, и за неделю ее в первый раз не написать. Желательно изучить TCL или Python и написать демона на них.
Стоит изучить межпроцессное взаимодействие, и, возможно, многопоточность, работу с неблокирующими сокетами и т.д.

Неприятно, но прийдется начальнику твоему решать, насколько это вам надо.

Или ищи совсем другие варианты.

-~{}~ 02.06.09 17:52:

>.....все форматирование сломалось

[ php ]
в скобках убрать пробелы и писать тут код
[ /php ]
 

WAS71

Новичок
.....начальник собственно я сам
суть задачи доставить данные с устройств на сервер, и аккуратненько сложить их в базу, устройств много 50-100-200
в принципе устраивал бы и сам HTTP шный сокет, т.е. обрабатывающий GET/POST запросы, НО
проблема такова что этот сокет рвет соединение после каждого запроса, (такова его сущность) - поэтому и пришлось создавать/открывать свои сокеты дабы соединение держалось постоянно или не разрывалось после каждого пакета, но кто то же должен инициировать создание сокета, виделось такое решение

первый запрос устройство шлет в HTTP протоколе
дальше если есть ИМей устройства в базе, создавать для него сокет и уже работать через него, но задача в лоб, не решилась
после приема http запроса - все остановилось
как сделать по другому еще пока не навеялось, вот собственно такая задача
 

Wicked

Новичок
в принципе устраивал бы и сам HTTP шный сокет, т.е. обрабатывающий GET/POST запросы, НО
проблема такова что этот сокет рвет соединение после каждого запроса, (такова его сущность)
http://en.wikipedia.org/wiki/HTTP_persistent_connections

-~{}~ 03.06.09 01:37:

я правильно понимаю, что когда запускается
http://82.47.200.5/imei.php?imei=353358013229955
, то именно этот скрипт (imei.php с помощью подключенного include'ом класса New_Socket) во время своего выполнения открывает порт и начинает его слушать?
 

AmdY

Пью пиво
Команда форума
я так понимаю проблема в сессиях, человеку просто нужно сохранять состояние между запросами, чтобы последующие запросы дописывали данные? в чём проблема? если программа не поддерживает куки, то можно передавать идентификатор прямо в урле.
 

WAS71

Новичок
все верно именно этот (imei.php) скрипт открывает порт и начинает его слушать, но я так понял что это работать не будет - вернее будет но только первый раз, потом все будет висеть в цикле Listenera и слушать порт

<TCL или Python и написать демона > - я пока не могу, незнаю как и времени нет изучить

-~{}~ 02.06.09 22:49:

to AmdY - все я уже перепробовал, но как сказал выше HTTP протокол не устраивает тем что разрывает сесию

а куков (или кукей) естественно нет, со стороны девайса ничего нет
только мой софт на Си и все что я напишу
 

AmdY

Пью пиво
Команда форума
плевать что разрывает, тебе же нужно только чтобы обратно востанавливал.
ты на си генеришь идентификатор и отсылаешь его с каждым запросом http://82.47.200.5/imei.php?id=<идентификатор_сессии>imei=353358013229955

-~{}~ 02.06.09 23:08:

хотя на самом деле куки можно легко эмулировать на си, раз уж асмовцы умудрялись.
 

WAS71

Новичок
тут не в возможности дело (FAT для карт памяти я думаю посложней будет, но работает)
а во времени (соединение 20-40-60 сек) и в трафике - каждый раз пересылать заголовки, накладно т.к. пакеты идут(пытаются идти) каждую секунду и за сутки это будет 86400*длину заголовков - ненужные данные

ну по моему я нашел решение, сокет создавать вместе с запуском сервера (пока вручную запускаю скрипт - не знаю как сделать запуск вместе с сервером)

и не разрывая соединения работать в пределах сесии
 

Макс

Старожил PHPClub
WAS71
а во времени (соединение 20-40-60 сек)
У тебя в схеме когда сначало идет запрос на imei.php а потом на сокет - будет 2 соединения, одно - по протоколу http, второе - для твоего сокета.
Речь идет о мобильных телефонах или о каких-то других специфических девайсах ?

накладно т.к. пакеты идут(пытаются идти) каждую секунду
То есть если у тебя будет 200 девайсов - то нагрузка 200 запросов в секунду ?
ИМХО твой код, который обрабатывает соединения не справится, потому как:
1. он на ПХП
2. полученые запросы будут обрабатываться последовательно
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
>полученые запросы будут обрабатываться последовательно

та не, там же каждый телефон откроет свою tcp-сессию
будет 200 дочек апача висеть на сокетах, открытых для телефонов

WAS71
Суп. Надо. Есть. ЛОЖКОЙ!
 

Wicked

Новичок
WAS71
итого твои проблемы с HTTP:
1) HTTP-сервер разрывает соединения после каждого запроса.
2) HTTP слишком избыточен для того, чтобы общаться с помощью него с сервером раз в секунду с мобильных устройств с дорогим трафиком.

Дак вот. Про постоянные http-соединения я уже писал. Про избыточность могу сказать, что можно слать минимум заголовков. Сильно мелкую коммуникацию тоже нету смысла делать: наверняка провы считают tcp-ip пакеты целиком, даже если они на 90% пустые.

Мое мнение - сначала нужно использовать постоянные http-соединение и поставить эксперимент или смоделировать, насколько при этом возрастают ли траты трафика по сравнению с более легковесным протоколом.

Если результаты окажутся неприемлемыми, то тогда уже стоит действительно садиться писать свой демон.

-~{}~ 03.06.09 11:09:

а еще неплохо было бы рассказать, какая работа проделывается сервером в самых тяжелых случаях
 

Макс

Старожил PHPClub
grigori
>полученые запросы будут обрабатываться последовательно

та не, там же каждый телефон откроет свою tcp-сессию
будет 200 дочек апача висеть на сокетах, открытых для телефонов
не будут 200 дочек висеть на сокетах - реально только _один_ ПХП-процесс сможет сделать socket_bind() для одного хост:порт. Все остальные будут получть address already in use и не будут работать
 

WAS71

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