Сокеты в php пишем простое клиент серверное приложение

PHPКомментариев нет

Вся работа будет осуществляться в Linux системе в которой установлен php. Для создания приложения будет использована только командная строка.

Для начала создадим каталог для нашего приложения

mkdir Server
cd Server

Создадим новый файл client.php который будет клиентом нашего приложения. И откроем файл для редактирования

touch client.php
vi client.php

Добавим в файл следующий код. Тут стоить отметить что у вас должен быть установлен php

#!/usr/bin/env php
<?php
// получим параметры из командной строки
$params = getopt('', ['address::', 'port::', "message"]);
// параметры соединения
$address = $params['address'] ?? '127.0.0.1';
$port = $params['port'] ?? 9999; // более 1024 менее 64000
$message = $params['message'] ?? "GET /";
$message .= "\n";

while(true)
{
        usleep(100000);
        // создаем сокет
        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($socket === false)
            die("Socket create failed: " . socket_strerror(socket_last_error())) . "\n";

        $connect = socket_connect($socket, $address, $port);
        if ($connect === false)
            die("Socket create failed: " . socket_strerror(socket_last_error())) . "\n";

        // отправим сообщение для сервера, в данном случае мы просим открыть главную страницу
        socket_write($socket, $message, strlen($message));

        // ожидаем ответ, второй параметр размер ожидаемого ответа
        $answer = '';
        while(($line = socket_read($socket, 2024)) !== ""){
            $answer .= $line;
        }

        // выводим ответ
        echo $answer . "\n";

        // закрываем соединение
        socket_close($socket);
}

Установим права на файл client.php для его выполнения

chmod +x client.php

Далее создадим файл server.php который будет отвечать за ответ сервера. И откроем файл для редактирования

touch server.php
vi server.php

Добавим в файл следующий код.

#!/usr/bin/env php
<?php
// получим параметры из командной строки 
$params = getopt('', ['address::', 'port::', 'threads::']);
// параметры соединения 
$address = $params['address'] ?? '127.0.0.1'; // адрес на машину которая подключается, у нас все локально 
$port = $params['port'] ?? 9999; // более 1024 менее 64000 
$threads = $params['threads'] ?? 1;
// создаем сокет для подключения 
$acceptor = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($acceptor === false)
    die("Socket create failed: " . socket_strerror(socket_last_error())) . "\n";

// указываем в опциях что можно перереиспользовать адрес
socket_set_option($acceptor, SOL_SOCKET, SO_REUSEADDR, 1);

// Привязывает имя, указанное в параметре address, к сокету, описанному в параметре socket
if(!socket_bind($acceptor, $address, $port))
    die("Socket create failed: " . socket_strerror(socket_last_error())) . "\n";

// Прослушивает входящие соединения на сокете
if(!socket_listen($acceptor, 1)) // максимальная очередь 1
    die("Socket create failed: " . socket_strerror(socket_last_error())) . "\n";
// для примера создадим 3 потока запросов(наш сервер сможет обслужить 3 запроса паралельно)
for($i = 0; $i < $threads; $i++)
{
// обработываем в несколько потоков
$pid = pcntl_fork();
if($pid === 0)
{
// обрабатываем запросы и отвечаем в цикле, для того что бы обрабатывать не один запрос
while(true)
{
    $socket = socket_accept($acceptor);
    echo "Accept connection $socket\n";

    // получим pid процесса
    $pid = posix_getpid();
    // отправим сообщение
    $message = "Hello from " . $pid . " proccess\n";
    socket_write($socket, $message);

    $command = socket_read($socket, 2024);
    $command = trim($command);
    echo "Retrieve command: $command\n";
    $message = "[" . $command . "]\n";
    socket_write($socket, $message);
    socket_close($socket);
}
}
}

// ждем закрытие всех соединений
while(($cid = pcntl_waitpid(0, $status)) != -1)
{
    $exitcode = pcntl_wexitstatus($status);
    echo "Child $cid exited with status $exitcode";
}
// закрываем соединение
socket_close($acceptor);

Установим права на файл client.php для его выполнения

chmod +x server.php

Откроем вторую консоль и запустим файл server

./server.php --address=127.0.0.1 --port=9999

Проверим какие процессы есть в системе

ps ux | grep php

В результате мы видим запущенный наш процесс, обратите в нимание на pid, который будет нам возвращен в клиенте

Запустим файл client в одной консоли

./client.php --address=127.0.0.1 --port=9999

 

 


Комментарии закрыты!