HugoBorz http://ru2.php.net/manual/en/sockets.examples.php - ковыряйте этот пример, тут все что вам нужно На всякий случай - не все хостинги позволят вам биндить произвольный порт и даже если позволят - не факт, что извне можно будет подключиться
Извиняюсь, что сразу не сообщил. Скрипт сам написан, и хостинг вполне позволяет открывать и конектиться к нему. Суть значит в следующем, после запуска скрипта я конекчусь на нужный порт (всё проходит как и нужно)... далее трабла первая, другой клиент при подключённом первом, соединиться уже не может, ну да ладно это ещё терпимо.... трабла вторая заключается в том, что после того как первый коннект отвалился, второй так и не может соединиться с сервером. В общем сори, что сразу не описал более подробно суть проблемы. Собственно сам код PHP: <? header('Content-Type: text/plain;'); error_reporting(E_ALL ^ E_WARNING); set_time_limit(0); ob_implicit_flush(); echo "-= Server =-\n\n"; $address = 'host'; $port = 10001; try { echo 'Create socket ... '; if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) { throw new Exception('socket_create() failed: '.socket_strerror(socket_last_error())."\n"); } else { echo "OK\n"; } echo 'Bind socket ... '; if (($ret = socket_bind($sock, $address, $port)) < 0) { throw new Exception('socket_bind() failed: '.socket_strerror(socket_last_error())."\n"); } else { echo "OK\n"; } echo 'Listen socket ... '; if (($ret = socket_listen($sock, 5)) < 0) { throw new Exception('socket_listen() failed: '.socket_strerror(socket_last_error())."\n"); } else { echo "OK\n"; } do { echo 'Accept socket ... '; if (($msgsock = socket_accept($sock)) < 0) { throw new Exception('socket_accept() failed: '.socket_strerror(socket_last_error())."\n"); } else { echo "OK\n"; } $msg = "Hello, Client!"; echo "Say to client ($msg) ... "; socket_write($msgsock, $msg, strlen($msg)); echo "OK\n"; do { if (false === ($buf = socket_read($msgsock, 1024))) { throw new Exception('socket_read() failed: '.socket_strerror(socket_last_error())."\n"); } else { } $data = $buf; $filename = "text.txt"; // Если файл существует и в него возможна запись if ( is_writeable($filename) ) : // Открыть файл и установить указатель текущей позиции в конец файла $fh = fopen($filename, "a+"); // Записать содержимое $data в файл $success = fwrite($fh, $data); // Закрыть файл fclose($fh); else : endif; if (!$buf = trim($buf)) { continue; } if ($buf == 'shutdown') { socket_close($msgsock); break 2; } socket_write($msgsock, $buf, strlen($buf)); } while (true); } while (true); } catch (Exception $e) { echo "\nError: ".$e->getMessage(); } if (isset($sock)) { echo 'Close socket ... '; socket_close($sock); echo "OK\n"; } ?> Заранее блогадарен всем, кто поможет в решении данной задачи.
Смотри в сторону ф-ии socket_select http://www.php.net/manual/en/function.socket-select.php Оа тебе позволит работать с несколькими коннектами. Там в юзер каментах есть неплохой пример реализации
Снова поднимаю тему. Кто может мне пояснить, в чём заключается проблема. Скрипт написал, коннекты ловит, всё как и полагалось, но работает около 10 минут, потом фиг знает что происходит и приконнектиться нереально. Процесс на серваке так и висит. После убивания процесса, перезапускаю скрипт, процесс запускается а приконнектиться никак, через ~30секунд процесс убиватся. Перезапускаю, история повторяется и так несколько раз. После некоторого секса он всётаки запускается и работает опять как нужно, но опять же непродолжительное время. Поясните плз, кто знает, в чём тут может быть проблема... может в скрипте, может в серваке...? Да кст пробовал в крон забить с переодичностью 10 минут, работает чуть дольше но проблемы не решает. Собсно код PHP: <?php error_reporting(E_ALL); ob_implicit_flush(); $address = 'server_ip'; $port = 10000; if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) { echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; } if (socket_bind($sock, $address, $port) === false) { echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; } if (socket_listen($sock, 5) === false) { echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; } do { if (($msgsock = socket_accept($sock)) === false) { echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; break; } $msg = "\nPHPServer for ZHUK" . "'quit' OR 'shutdown'.\n"; socket_write($msgsock, $msg, strlen($msg)); do { if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) { echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n"; break 2; } if (!$buf = trim($buf)) { continue; } if ($buf == '*') { break; } if ($buf == 'shutdown') { socket_close($msgsock); break 2; } // тут запись в файл break; $talkback = "PHP: You said '$buf'.\n"; socket_write($msgsock, $talkback, strlen($talkback)); echo "$buf\n"; } while (true); socket_close($msgsock); } while (true); socket_close($sock); ?>
b3 правильно подсказал. Возможно, твой хостинг не поддерживает установки времени максимального выполнения скрипта. Обычно, так оно и есть.
Создай у себя на хостинге PHP файл с таким содержимым: PHP: <?php phpinfo(); ?> И перейди на этот скрипт из браузера. Увидишь где то на странице поле max_execution_time, в котором в секундах написано максимальное время выполнения скрипта. Сможешь узнать хотя бы, действительно ли проблема в хостинге.
30 написано... это по умолчанию вроде. я жопой чую что проблема в хостинге, но не могу понять именно в чём п.с. хотя может и в скрипте косяк... планка съезжает уже может break гдето убрать?
всё парни, решил я свою проблему ценой бессонной ночи. проблема была не в хостинге, а именно в скрипте и опредилённых запросах к нему. В общем суть была такая, может комуто помогу. Скрипт работает как нужно, только если запрос на сервак приходит с какимито данными, т.е., благодаря вот этой штуке PHP: if (!$buf = trim($buf)) { continue; } пустой запрос или запрос содержащий пробелы, вызывал ступор и коннект так и весел всё время. косяк был исправлен заменой континью на брик, всё летает и обрабатывается как положено. Всем кто помогал разобраться респект. Спасибо парни. Всем удачи.
Снова ап. В общем проблема в подвисании всей этой ботвы. Всё вроде работало а тут снова таже хрень, даже низнаю что ещё педелать, может кто что посоветует. Значит опишу проблему ещё раз. Запускаю скрипт, процесс висит, всё ровно, все запросы обрабатываются, но в какойто момент, при подключении пишет коннект и всё ждёт, я так понимаю, что скрипт ставит в очередь моё соединение, пока не закроется предыдущее, только трабла в том, что предыдущий запрос обработан и соединение по идеи должно быть закрыто. В чём тут может быть проблема подскажите плиз, а то какой день уже бьюсь, всё никак не выходит. PHP: <?php error_reporting(E_ALL); /* Allow the script to hang around waiting for connections. */ @set_time_limit(0); @ini_set('max_execution_time', 0); /* Turn on implicit output flushing so we see what we're getting * as it comes in. */ ob_implicit_flush(); $address = 'HOST_IP'; $port = HOST_PORT; if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) { echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; } if (socket_bind($sock, $address, $port) === false) { echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; } if (socket_listen($sock, 5) === false) { echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; } do { if (($msgsock = socket_accept($sock)) === false) { echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n"; break; } /* Send instructions. */ $msg = "\nPHPServer." . "'quit' OR 'shutdown'.\n"; socket_write($msgsock, $msg, strlen($msg)); do { if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) { echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n"; break 2; } if (!$buf = trim($buf)) { break; } if ($buf == '*') { break; } if ($buf == 'shutdown') { socket_close($msgsock); break 2; } $data = $buf; ЗДЕСЬ ПИШЕМ ЗАПРОС В ФАЙЛ break; $talkback = "PHP: You said '$buf'.\n"; socket_write($msgsock, $talkback, strlen($talkback)); echo "$buf\n"; } while (true); socket_close($msgsock); } while (true); socket_close($sock); ?>
Посмотрите этот пример. http://ru2.php.net/manual/en/function.socket-select.php#56241 Это простенький многопользовательский чат. Правда в таком виде он будет нещадно грузить проц, поэтому в функции socket_select четвертым параметром пропишите 120 А в вашем коде проблема, имхо, в PHP_NORMAL_READ - пхп в блокирующем режиме ожидает символ перевода строки. Попробуйте исправить на PHP_BINARY_READ, но тут вы встретите другую проблему, если обращаетесь к скрипту не с помощью других скриптов
Я пробовал ваш пример ещё ранее и действительно процессор нагружало не хило, поставил 120 вместо 0, проц теперь не грузит, но сам процесс вылетает всёравно, примерно секунд 30-40 робит и всё. Что можете подсказать по этому поводу? Может какимто образом можно решить проблему с символом перевода строки, так как в бинарном режиме для моей задачи решение не подходит. И остаётся ещё вопрос, по какой причине процесс может закрываться. Иногда работает долго и всё в порядке, а бывает процесс падает через несколько минут работы.
HugoBorz Прочитайте какую-нибудь книгу про клиент-серверное программирование/проектирование. Если ваш скрипт работает, а скрипт по моей последней ссылке - нет, то попробуйте добавить в него строки: PHP: @set_time_limit(0); @ini_set('max_execution_time', 0); Создайте буфер, в который будут складываться принятые данные, если в новой порции есть символы \r \n - то отправляете/обрабатывайте данные вплоть до этого знака, и соответственно удаляете их из буфера. Возможно, проблема еще в этой строке: false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ) Попробуйте заменить эти строки: PHP: if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) { echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n"; break 2; } if (!$buf = trim($buf)) { break; } На эти: PHP: $buf = socket_read($msgsock, 2048, PHP_BINARY_READ); if ($buf === false || strlen($buf)<1) { break; } И вместо socket_close($msgsock); написать if ($msgsock) socket_close($msgsock); Ну и если проблема не в ошибках скрипта, то вариантов - куча. Например, на время работы может влиять способ запуска (из браузера/из коммандной строки), сервер может выгружать скрипты, при превышении использования памяти на аккаунт и так далее. Проще связаться с тех. поддержкой хостинга и спросить, какие их настройки могут влиять на данный скрипт
В общем опишу основные проблемные места. 1. работа осуществляется с блокируемыми сокетами. Это означает что пока у тебя полностью не отработает одно соединение второе принять нельзя. Т.е. немогут одновременно подцепиться 2 клиента. Сильно рекомендую использовать неблокируемые сокеты. Для этого после socket_accept нужно делать socket_set_nonblock и разруливать чтение из сокетов через socket_select. 2. Если всё-таки собираешься юзать блокируемые сокеты, то тебе потребуется stream_set_timeout. 3. Проверку на чтение из блокируемого сокета лучше всего реализовать через stream_get_meta_data 4. socket_write может вернуть ошибку. обрабатывать её тоже неплохо бы. Будут ещё вопросы - в ПМ, легко отвечу. Много собак съел))))