Position actuelle: Accueil> Derniers articles> Comportement de blocage typique et méthodes d'adaptation de socket_accept ()

Comportement de blocage typique et méthodes d'adaptation de socket_accept ()

M66 2025-05-18
<?php

// Cet article discutera en profondeur PHP Un problème typique qui est souvent rencontré dans la programmation réseau:socket_accept() Blocage des fonctions。Nous analyserons les causes,Il fournit également une série de stratégies d&#39;adaptation et de techniques d&#39;optimisation,Aide les développeurs à créer des services de réseau hautement disponibles plus efficacement。

// ----------------------------------------------

/**
 * Comment le résoudre socket_accept() Problèmes de blocage typiques dans les fonctions?Méthodes d&#39;adaptation et techniques d&#39;optimisation
 *
 * Utilisé PHP Lors du développement du serveur réseau,socket Joue un rôle extrêmement important。
 * En particulier socket_accept() fonction,Il écoute socket En attente de connexion,Il y aura un blocage,
 * Provoque le programme pour continuer à effectuer d&#39;autres tâches,Cela réduit la réponse du système et les performances de la concurrence。
 * Cet article discutera en profondeur该问题de原因,并提供几种常见deMéthodes d&#39;adaptation et techniques d&#39;optimisation。
 */

// un、Analyse des problèmes:Pourquoi socket_accept() Bloquera?

/*
socket_accept() Oui PHP de Socket Étendu中deun个fonction,用于接受un个来自客户端de连接请求。
其工作机制Oui在un个监听中de socket En attente de connexion,Lorsqu&#39;il y a une demande client,它才会返回un个新de socket ressource。

Cependant,Si appelez socket_accept() heure,没有新de连接到来,fonction将会un直阻塞在那里,Jusqu&#39;à ce qu&#39;une connexion se produit。
Cela fait que le programme ne peut pas être exécuté à la baisse,Cela affecte le processus global。
*/

// deux、解决方法un:Définir le mode non bloquant

/*
最直接de方式Oui将 socket Réglé sur le mode non bloquant。
Dans ce mode,socket_accept() 不会un直等待连接,S&#39;il n&#39;y a pas de connexion,Il reviendra immédiatement false。
*/

$address = '0.0.0.0';
$port = 9000;

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

// Définir le mode non bloquant
socket_set_nonblock($server);

echo "Server listening on {$address}:{$port}\n";

while (true) {
    $client = @socket_accept($server);
    if ($client === false) {
        // Pas de connexion,Exécuter une autre logique
        echo "En attente de connexion...\n";
        usleep(500000); // Dormir 0.5 Deuxième
        continue;
    }

    // Connexions de traitement
    socket_write($client, "Bienvenue pour se connecter m66.net Servir!\n");
    socket_close($client);
}

// trois、解决方法deux:utiliser socket_select() Implémenter le multiplexage

/*
socket_select() Ouiun种Multiplexage机制,允许我们同heure监听多个 socket,Seulement quand socket 准备好接收连接heure,Nous appelons socket_accept()。
这Ouiun种更灵活和性能更优de方式。
*/

$readSockets = [$server];
$write = null;
$except = null;

while (true) {
    $read = $readSockets;

    if (socket_select($read, $write, $except, 1) > 0) {
        foreach ($read as $sock) {
            if ($sock === $server) {
                $client = socket_accept($server);
                if ($client) {
                    socket_write($client, "Vous vous êtes connecté avec succès à m66.net!\n");
                    socket_close($client);
                }
            }
        }
    } else {
        echo "Aucune demande de connexion encore,Continuez à d&#39;autres tâches。\n";
    }
}

// Quatre、解决方法trois:utiliser多进程ou多线程机制

/*
Bien que PHP 并不Ouiun个天然支持多线程de语言,Mais nous pouvons utiliser le pcntl_fork() 实现多进程来并发Connexions de traitement。
donc,Le processus principal continue d&#39;écouter,Le processus de l&#39;enfant est responsable de la gestion des demandes des clients,Pour éviter de bloquer les problèmes。
*/

// Cette méthode convient à CLI 模式de PHP,具体实现需注意子进程ressource回收和并发限制等问题。

// cinq、Suggestions d&#39;optimisation supplémentaires

/*
1. 设置合理de socket 超heureheure间,éviter socket L&#39;opération est indéfiniment。
2. utiliser event Étendu(comme libevent)Effectuer un développement axé sur les événements,Améliorer la capacité de concurrence。
3. Combiné dans un environnement de production Nginx ou Swoole 提供异步高性能网络Servir。
*/

// six、Résumer

/*
socket_accept() 阻塞问题Bien que常见,Mais via le mode non bloquant、socket_select() Multiplexage、甚至utiliser多进程等方式,Peut être traité efficacement。
La clé est de peser la complexité et les performances en fonction des exigences du projet,选择最合适de方案。
Pour l&#39;espoir de renforcer la haute disponibilité、低延迟网络Servirde PHP Pour les développeurs,理解并掌握这些技巧Oui非常必要de。
*/

?>