Maison  >  Article  >  développement back-end  >  Écrire des programmes Socket de base en PHP

Écrire des programmes Socket de base en PHP

藏色散人
藏色散人avant
2019-11-18 14:11:033658parcourir

Avertissez les jeunes

Les utopies sont inutiles. La capacité personnelle vient du travail acharné de chaque jour, plutôt que d'atteindre le ciel d'un seul coup. Un jour, chaque goutte d’eau pénétrera dans la pierre. Il fera sombre et les fleurs seront lumineuses.

Mon objectif

Parce que dans ma future étude, je pourrai peut-être utiliser du contenu réseau, mais en même temps, de nombreux codeurs qui écrivent PHP n'ont jamais écrit de programme sockets, mais J'ai dû en entendre parler, et j'ai dû entendre parler du mot programmation réseau, donc pour un apprentissage futur, je prévois d'expliquer brièvement les connaissances pertinentes ici. Cet article de blog est accompagné d'un exemple de programme et le code est hébergé sur Code Cloud. (php-socket-base-code : https://gitee.com/obamajs/php-socket-base-code), il vous suffit de le télécharger, de configurer l'environnement approprié et de suivre les instructions pour l'exécuter.

Configuration de l'environnement

La programmation du socket doit activer l'extension socket de php L'ordinateur que j'utilise est Windows, il vous suffit donc ici d'ouvrir le fichier php.ini. et trouvez cette ligne Supprimez simplement les commentaires

extension=sockets

Document officiel

L'adresse officielle de la programmation des sockets php est : php socket (https://www.php.net /manual/ fr/book.sockets.php)

Programmation côté serveur

La programmation socket suit certaines étapes de programmation. Ces étapes sont indispensables. La programmation client et serveur est. différent, regardons d'abord le serveur.

Écrire des programmes Socket de base en PHP

Create Socket

Les sockets sont des ressources système. On appelle d'abord la méthode socket_create (se référer à la documentation officielle : https: /. /www.php.net/manual/en/function.socket-create.php), l'appel est le suivant :

$this->socket_handle = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$this->socket_handle) {
      //创建失败抛出异常,socket_last_error获取最后一次socket操作错误码,socket_strerror打印出对应错误码所对应的可读性描述
     throw new Exception(socket_strerror(socket_last_error($this->socket_handle)));
} else {
          echo "create socket successful\n";
}

Le premier paramètre précise si le socket actuel utilise ipv4 ou ipv6, si oui Si le Dans le premier cas, passez AF_INET, sinon AF_INET6. Bien sûr, il existe un autre type, qui est AF_UNIX. Nous n'en parlerons pas pour le moment. Nous choisissons généralement AF_INET (ipv6 n'est pas très populaire).

Le deuxième paramètre précise le type de protocole. Généralement, TCP ou UDP est sélectionné. TCP est une transmission en streaming fiable (la plus largement utilisée dans la vie, garantissant fiabilité et sécurité), alors qu'UDP ne l'est pas, ce paramètre. sélectionne généralement TCP.

Le troisième est SOL_TCP si vous avez sélectionné TCP auparavant, sinon c'est SOL_UDP.

Adresse de liaison et numéro de port

Étant donné qu'un hôte peut avoir plusieurs adresses IP, vous devez spécifier celle que votre socket écoute, couramment utilisée. La valeur est 127,0 .0.1, ou écouter toutes les adresses 0.0.0.0 Donc quelqu'un ici pourrait ne pas comprendre quelle est la différence entre 127.0.0.1 et 0.0.0.0 ? 127.0.0.1 n'est qu'une adresse de bouclage et ne peut être utilisée que pour un accès local. Pour parler franchement, vous pouvez l'utiliser vous-même. Parce que cette adresse IP n'est pas ouverte au monde extérieur, personne ne peut accéder à cette adresse, donc si votre serveur est présent. l'adresse est définie sur 127.0 0.1, si d'autres veulent y accéder, ils ne peuvent qu'aller dans la merde.

0.0.0.0 n'est pas strictement une adresse IP. Cela signifie que toutes les adresses IP de cette machine sont les miennes, haha.

Compris ce qui précède, jetons un œil au code appelant

if (!socket_bind($this->socket_handle, $this->addr, $this->port)) {
         throw new Exception(socket_strerror(socket_last_error($this->socket_handle)));
    } else {
         echo "bind addr successful\n";
 }

Est-ce très simple ? Le premier paramètre est le résultat renvoyé par socket_create, et le deuxième paramètre est l'adresse ci-dessus ? est déjà Comme mentionné, le troisième paramètre est le numéro de port.

Socket d'écoute

Après les étapes ci-dessus, nous venons de créer un socket et d'y associer le numéro de port et l'adresse, mais qu'en est-il du système, savez-vous que c'est le cas ? une prise d'écoute ? Donc, notre travail n'est pas encore terminé, il faut donc le dire. Ne me dites pas que vous êtes en bonne relation avec le système ! ! !

if (!socket_listen($this->socket_handle, $this->back_log)) {
      throw new Exception(socket_strerror(socket_last_error($this->socket_handle)));
  } else {
      echo "socket  listen successful\n";
 }

Le deuxième paramètre mérite d'être expliqué. Veuillez m'écouter en détail pour chaque processus du système Linux, le système maintient une file d'attente de sockets (premier entré, premier sorti). dit sur la base du premier arrivé, premier servi), il faut du temps au programme de niveau supérieur pour traiter la logique métier, alors attendez. Alors, quelle est la taille de cette file d’attente ? Sa valeur est le deuxième paramètre, puis-je la définir sur une valeur élevée ? Saonian, tu réfléchis trop ? Cette valeur est différente selon les systèmes. Ne dites pas que je vous trompe. Voir ci-dessous.

The maximum number passed to the backlog parameter highly depends on the underlying platform. On Linux, it is silently truncated to SOMAXCONN. On win32, if passed SOMAXCONN, the underlying service provider responsible for the socket will set the backlog to a maximum reasonable value. There is no standard provision to find out the actual backlog value on this platform.

Vous n'avez pas à vous soucier des données exactes de cette valeur, cela n'a aucun sens.

Tout est prêt, il ne nous manque que le vent d'est

Après l'opération ci-dessus, nous pouvons commencer à accepter les connexions du client, et cette fonction est encore plus simple

$client_socket_handle = socket_accept($this->socket_handle);

La valeur de retour de cette fonction est également un handle de socket, vous pouvez donc la lire et l'écrire. Dans l'exemple de programme actuel, ce que nous faisons est très simple, si simple que vous pouvez douter de votre vie.

 $client_socket_handle = socket_accept($this->socket_handle);
        if (!$client_socket_handle) {
            echo "socket_accept call failed\n";
            exit(1);
        } else {
            while (true) {
                $bytes_num = socket_recv($client_socket_handle, $buffer, 100, 0);
                if (!$bytes_num) {
                    echo "socket_recv  failed\n";
                    exit(1);
                } else {
                    echo "content from client:" . $buffer . "\n";
                }
            }
        }

Lire le socket

En prenant l'exemple ci-dessus comme exemple, nous utilisons socket_recv pour lire le contenu du client. Cette fonction est très simple. comme suit

socket_recv ( resource $socket , string &$buf , int $len , int $flags ) : int

Le contenu lu sera renvoyé dans le deuxième paramètre. Le deuxième paramètre transmet le nombre de caractères que nous voulons lire. Le quatrième paramètre peut être directement défini sur 0. La valeur de retour de cette fonction est. la valeur lue réelle. Le nombre d'octets pris.

Programmation Client

客户端相对于服务端来说,就很简单了,流程如下

Écrire des programmes Socket de base en PHP

创建套接字前面已经讲过了,不再详述,客户端只需要连接服务器即可,函数为 socket_create,我们来看一哈在当前的例子中,我们是如何调用的。

if (!socket_connect($this->socket_handle, $this->server_addr, $this->server_port)) {
            echo socket_strerror(socket_last_error($this->socket_handle)) . "\n";
            exit(1);
        } else {
            while (true) {
                $data = fgets(STDIN);
                //如果用户输入quit,那么退出程序
                if (strcmp($data, "quit") == 0) {
                    break;
                }
                socket_write($this->socket_handle, $data);
            }
        }

该函数只需要指定服务器的地址和端口号即可,参数是不是很简单

练习实例

在讲解基本函数调用的时候,我就把自带程序的核心部分,复制出来了,如果要完整的程序,这里是地址(php-socket-base-code:https://gitee.com/obamajs/php-socket-base-code),代码非常简单,再次提醒,这些代码完全是用于给大家讲解基本的 socket 变成操作,为大家以后的学习打下基础,那么如何使用这个例子程序呢?

进入到命令行,开启服务器程序

php TcpServer.php,

打开另外一个命令行界面,

php TcpClient.php,

在客户端界面,输入任何文本,再输入回车,再切换到服务器界面,您将会看到客户端输入的内容

在笔者的电脑上操作实例截图如下:

Écrire des programmes Socket de base en PHP

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer