• Сокеты в 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

     

     


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