Maison  >  Article  >  développement back-end  >  Contenu de communication du socket PHP

Contenu de communication du socket PHP

不言
不言original
2018-04-23 10:12:351190parcourir

Cet article présente principalement la communication socket de PHP, qui a une certaine valeur de référence. Maintenant, je le partage avec vous. Les amis dans le besoin peuvent s'y référer

Que sont TCP/IP et UDP ?


TCP/IP (Transmission Control Protocol/Internet Protocol) est un protocole standard industriel conçu pour les réseaux étendus (WAN).
UDP (User Data Protocol) est un protocole correspondant à TCP. Il fait partie de la suite de protocoles TCP/IP.
Voici un schéma montrant la relation entre ces protocoles.
Contenu de communication du socket PHP
La suite de protocoles TCP/IP comprend la couche transport, la couche réseau et la couche liaison. Vous connaissez maintenant la relation entre TCP/IP et UDP.
Où est la prise ?
Sur la figure 1, nous ne voyons pas l’ombre de Socket, alors où est-elle ? Laissons les images parler d’elles-mêmes.
Contenu de communication du socket PHP

Qu'est-ce que Socket ?

Socket est une couche d'abstraction logicielle intermédiaire pour la communication entre la couche application et la suite de protocoles TCP/IP. En mode conception, Socket est en fait un mode façade, qui cache la famille complexe de protocoles TCP/IP derrière l'interface Socket. Pour les utilisateurs, un ensemble d'interfaces simples permet à Socket d'organiser les données pour répondre aux exigences spécifiées.
Comment ça marche
Contenu de communication du socket PHP
Commençons par le côté serveur. Le serveur initialise d'abord le Socket, puis se lie au port, écoute le port, appelle Accept to Block et attend que le client se connecte. A ce moment, si un client initialise un Socket puis se connecte au serveur (connect), si la connexion réussit, la connexion entre le client et le serveur est établie. Le client envoie une demande de données, le serveur reçoit la demande et traite la demande, puis envoie les données de réponse au client, le client lit les données et ferme enfin la connexion, et l'interaction se termine.

Fonctions liées au socket :

socket_accept() accepte une connexion Socket
socket_bind() lie le socket à une adresse IP et un port
socket_clear_error() efface l'erreur de socket ou code d'erreur final
socket_close() Ferme une ressource socket
socket_connect() Démarre une connexion socket
socket_create_listen() Ouvre un écouteur de socket sur le port spécifié
socket_create_pair() Génère une paire Il n'y a pas différence entre placer le socket dans un tableau
socket_create() génère un socket, ce qui équivaut à générer une structure de données de socket
socket_get_option() obtient l'option de socket
socket_getpeername() obtient l'adresse IP d'une télécommande hôte similaire
socket_getsockname() Obtient l'adresse IP du socket local
socket_iovec_add() Ajoute un nouveau vecteur à un tableau dispersé/agrégé
socket_iovec_alloc() Cette fonction crée une structure de données iovec qui peut envoyer, recevoir , lire et écrire
socket_iovec_delete() supprime un iovec alloué
socket_iovec_fetch() renvoie les données de la ressource iovec spécifiée
socket_iovec_free() libère une ressource iovec
socket_iovec_set() définit la nouvelle valeur de iovec data
socket_last_error() Obtenez le dernier code d'erreur de la socket actuelle
socket_listen() Écoutez toutes les connexions de la socket spécifiée
socket_read() Lisez les données de la longueur spécifiée
socket_readv() Lire les données du tableau scatter/agrégat
socket_recv() Terminer les données du socket vers le cache
socket_recvfrom() Accepter les données du socket spécifié, si non spécifié, le socket actuel sera par défaut
socket_recvmsg( ) Recevoir des messages d'iovec
socket_select() Sélection multicanal
socket_send() Cette fonction envoie des données au socket connecté
socket_sendmsg() Envoie un message à socket
socket_sendto() Envoie un message à le socket à l'adresse spécifiée
socket_set_block() Définissez-le dans le socket en mode bloc
socket_set_nonblock() Définissez le socket en mode non-bloc
socket_set_option() Définissez l'option du socket
socket_shutdown() Cette fonction vous permet de fermer la lecture, l'écriture ou le socket spécifié
socket_strerror() Renvoyer l'erreur détaillée du numéro d'erreur spécifié
socket_write() Écrire les données dans le cache du socket
socket_writev() Écrire les données dans un format dispersé/agrégé array

Cas : démonstration de communication socket

Côté serveur :

<?php //确保在连接客户端时不会超时
set_time_limit(0);

$ip = &#39;127.0.0.1&#39;;
$port = 1935;

/*
 +-------------------------------
 *    @socket通信整个过程
 +-------------------------------
 *    @socket_create
 *    @socket_bind
 *    @socket_listen
 *    @socket_accept
 *    @socket_read
 *    @socket_write
 *    @socket_close
 +--------------------------------
 */

/*----------------    以下操作都是手册上的    -------------------*/
if(($sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP)) < 0) {
    echo "socket_create() 失败的原因是:".socket_strerror($sock)."\n";
}

if(($ret = socket_bind($sock,$ip,$port)) < 0) {
    echo "socket_bind() 失败的原因是:".socket_strerror($ret)."\n";
}

if(($ret = socket_listen($sock,4)) < 0) {
    echo "socket_listen() 失败的原因是:".socket_strerror($ret)."\n";
}

$count = 0;

do {
    if (($msgsock = socket_accept($sock)) < 0) {
        echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
        break;
    } else {
        
        //发到客户端
        $msg ="测试成功!\n";
        socket_write($msgsock, $msg, strlen($msg));
        
        echo "测试成功了啊\n";
        $buf = socket_read($msgsock,8192);
        
        
        $talkback = "收到的信息:$buf\n";
        echo $talkback;
        
        if(++$count >= 5){
            break;
        };
        
    
    }
    //echo $buf;
    socket_close($msgsock);

} while (true);

socket_close($sock);
?>

Enregistrez et exécutez ce fichier. Exécutez netstat -ano pour vérifier l'état du port. Le mien est le port 1935
Le port est à l'écoute, ce qui signifie qu'il écoute. Ensuite, il nous suffit d'exécuter le programme client pour nous connecter.
Client :

<?php error_reporting(E_ALL);
set_time_limit(0);
echo "<h2>TCP/IP Connection\n";

$port = 1935;
$ip = "127.0.0.1";

/*
 +-------------------------------
 *    @socket连接整个过程
 +-------------------------------
 *    @socket_create
 *    @socket_connect
 *    @socket_write
 *    @socket_read
 *    @socket_close
 +--------------------------------
 */

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket $in <br>";
}

while($out = socket_read($socket, 8192)) {
    echo "接收服务器回传信息成功!\n";
    echo "接受的内容为:",$out;
}


echo "关闭SOCKET...\n";
socket_close($socket);
echo "关闭OK\n";
?>

Exécuter le serveur et renvoyer les informations au client, jusqu'à présent le client s'est connecté au serveur

Code détaillé explication

// 设置一些基本的变量
$host = "192.168.1.99";
$port = 1234;
// 设置超时时间
set_time_limit(0);
// 创建一个Socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not createsocket\n");
//绑定Socket到端口
$result = socket_bind($socket, $host, $port) or die("Could not bind tosocket\n");
// 开始监听链接
$result = socket_listen($socket, 3) or die("Could not set up socketlistener\n");
// accept incoming connections
// 另一个Socket来处理通信
$spawn = socket_accept($socket) or die("Could not accept incomingconnection\n");
// 获得客户端的输入
$input = socket_read($spawn, 1024) or die("Could not read input\n");
// 清空输入字符串
$input = trim($input);
//处理客户端输入并返回结果
$output = strrev($input) . "\n";
socket_write($spawn, $output, strlen ($output)) or die("Could not write output\n");
// 关闭sockets
socket_close($spawn);
socket_close($socket);

Ce qui suit est une description détaillée de chaque étape :
1. La première étape consiste à établir deux variables pour enregistrer l'adresse IP et le port du serveur sur lequel se trouve le Socket. en cours d'exécution. Vous pouvez définir Fournissez votre propre serveur et votre propre port (le port peut être un nombre compris entre 1 et 65535), à condition que ce port ne soit pas utilisé

.
// 设置两个变量
$host = "192.168.1.99";
$port = 1234;

2.在服务器端可以使用set_time_out()函数来确保PHP在等待客户端连接时不会超时.

// 超时时间
set_time_limit(0);

3.在前面的基础上,现在该使用socket_creat()函数创建一个Socket了—这个函数返回一个Socket句柄,这个句柄将用在以后所有的函数中.

// 创建Socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");

第一个参数”AF_INET”用来指定域名;
第二个参数”SOCK_STREM”告诉函数将创建一个什么类型的Socket(在这个例子中是TCP类型)

因此,如果你想创建一个UDP Socket的话,你可以使用如下的代码:

// 创建 socket
$socket = socket_create(AF_INET, SOCK_DGRAM, 0) or die("Could not create socket\n");

4.一旦创建了一个Socket句柄,下一步就是指定或者绑定它到指定的地址和端口.这可以通过socket_bind()函数来完成.

// 绑定 socket to 指定地址和端口
$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");

5.当Socket被创建好并绑定到一个端口后,就可以开始监听外部的连接了.PHP允许你由socket_listen()函数来开始一个监听,同时你可以指定一个数字(在这个例子中就是第二个参数:3)

// 开始监听连接
$result = socket_listen($socket, 3) or die("Could not set up socket listener\n");

6.到现在,你的服务器除了等待来自客户端的连接请求外基本上什么也没有做.一旦一个客户端的连接被收到,socket_accept()函数便开始起作用了,它接收连接请求并调用另一个子Socket来处理客户端–服务器间的信息.

//接受请求链接
// 调用子socket 处理信息
$spawn = socket_accept($socket) or die("Could not accept incoming connection\n");

这个子socket现在就可以被随后的客户端–服务器通信所用了.
7.当一个连接被建立后,服务器就会等待客户端发送一些输入信息,这写信息可以由socket_read()函数来获得,并把它赋值给PHP的$input变量.

// 读取客户端输入
$input = socket_read($spawn, 1024) or die("Could not read input\n");

socker_read的第而个参数用以指定读入的字节数,你可以通过它来限制从客户端获取数据的大小.
注意:socket_read函数会一直读取壳户端数据,直到遇见n,t或者0字符.PHP脚本把这写字符看做是输入的结束符.
8.现在服务器必须处理这些由客户端发来是数据(在这个例子中的处理仅仅包含数据的输入和回传到客户端).这部分可以由socket_write()函数来完成(使得由通信socket发回一个数据流到客户端成为可能)

// 处理客户端输入并返回数据
$output = strrev($input) . "\n";
socket_write($spawn, $output, strlen ($output)) or die("Could not write output\n");

9.一旦输出被返回到客户端,父/子socket都应通过socket_close()函数来终止

// 关闭 sockets
socket_close($spawn);
socket_close($socket);

相关推荐:

php实现socket的方法 

PHP之Socket服务器搭建和测试实例分享

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:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn