Maison >développement back-end >tutoriel php >La série PHP+Socket réalise la transmission de données entre le client et le serveur

La série PHP+Socket réalise la transmission de données entre le client et le serveur

藏色散人
藏色散人avant
2023-02-02 11:35:015009parcourir

Cet article vous apporte des connaissances pertinentes sur php+socket. Il présente principalement qu'est-ce que socket ? Comment php+socket réalise-t-il la transmission de données client-serveur ? Les amis intéressés peuvent jeter un œil ci-dessous. J'espère que cela sera utile à tout le monde.

Introduction au socket

réalise la communication entre les processus réseau. Presque toutes les applications utilisent des sockets. Les sockets sont la couche d'abstraction intermédiaire pour la communication entre la couche d'application et la famille de protocoles TCP/IP. En mode conception, le socket est en fait un mode façade, qui cache la famille complexe de protocoles TCP/IP derrière l'interface du socket. Pour les utilisateurs, un ensemble d'interfaces simples est tout, permettant au socket d'organiser les données pour se conformer aux spécifications. La signification anglaise originale du protocole

La série PHP+Socket réalise la transmission de données entre le client et le serveur

socket est « trou » ou « socket ». Il est aussi souvent appelé « socket ». Il est utilisé pour décrire les adresses IP et les ports. utilisé pour implémenter différentes communications entre des machines virtuelles ou différents ordinateurs.

Trois processus de lien de socket

  • Surveillance du serveur : IP + numéro de port

  • Demande client : émettre une demande de connexion à l'IP et au port du serveur

  • Confirmation du lien : surveillance du socket du serveur À la réception ou à la réception d'un demande de connexion au socket client, il créera un nouveau processus et enverra la description du socket du serveur au client en réponse à la demande du client. Une fois que le client aura confirmé cette description, la connexion est établie. Le socket du serveur reste à l'état d'écoute et continue d'accepter les demandes de connexion provenant d'autres sockets clients.

La série PHP+Socket réalise la transmission de données entre le client et le serveur

php implémente les sockets

Si vous devez utiliser des sockets en php, vous devez ajouter l'élément de configuration --enable-sockets lors de la compilation de php pour l'activer. Commande php -m|grep sockets pour vérifier l'état d'activation. Pour un processus de compilation spécifique, veuillez vous référer à Cet article--enable-sockets 配置项来启用,可使用 php -m|grep sockets 命令检查启用情况,具体编译过程可参考 这篇文章

快速体验

服务端与客户端简略代码如下,运行后服务端会阻塞等待客户端连接,客户端会在控制台要求输入内容,输入后信息会在服务端打印,同时客户端显示转为大写的内容,此示例服务端与客户端运行在一台服务器:

服务端监听

<?php

// 创建套接字
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// 设置 ip 被释放后立即可使用
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, true);

// 绑定ip与端口
socket_bind($socket, 0, 8888);

// 开始监听
socket_listen($socket);

while (true) {
    // 接收内容
    $conn_sock = socket_accept($socket);
    socket_getpeername($conn_sock, $ip, $port);
    // echo &#39;请求ip: &#39; . $ip . PHP_EOL . &#39;端口: &#39; . $port;

    while (true) {
        // 获取消息内容
        $msg = socket_read($conn_sock, 10240);
        // TODO 处理业务逻辑

        // 将信息转为大写并原样返回客户端
        socket_write($conn_sock, strtoupper($msg));

        echo $msg;
    }
}

客户端连接

<?php

// 创建套接字
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

// 连接服务端
socket_connect($socket, &#39;127.0.0.1&#39;, 8888);

while (true) {
    // 让控制台输入内容
    fwrite(STDOUT, &#39;请输入内容:&#39;);
    $in = fgets(STDIN);

    // 向服务端发送内容
    socket_write($socket, $in);

    // 读取服务端发送的消息
    $msg = socket_read($socket, 10240);
    echo $msg;
}

语法解释

socket_create

socket_create(int $domain,int $type, int $protocol): resource|false

创建并返回一个套接字资源,通常也称作一个通讯节点。一个典型的 socket 由至少 2 个套接字组成,其中一个运行在客户端,一个运行在服务端。

参数:

  • domain 指定当前套接字使用什么协议,可用协议如下:

    Domain 描述
    AF_INET IPv4 网络协议,TCP 与 UDP 都可使用此协议
    AF_INET6 IPv6 网络协议,TCP 与 UDP 都可使用此协议
    AF_UNIX 本地通讯协议,具有高性能与低成本的 IPC
  • type

    Expérience rapideLes codes simples du serveur et du client sont les suivants. Après l'exécution, le serveur bloquera et attendra le client pour se connecter, et le client demandera du contenu de saisie sur la console. Après la saisie, les informations seront imprimées sur le serveur et le client affichera le contenu converti en majuscules. Cet exemple de serveur et de client s'exécute sur le même serveur :
    socket_bind(resource $socket, string $address [, int $port]): bool
    Connexion clientCréez et renvoyez une ressource socket, généralement également appelée nœud de communication. Un socket typique se compose d’au moins 2 sockets, un exécuté côté client et un exécuté côté serveur. Paramètres : DescriptionAF_INET.
    Écoute du serveur
    socket_listen(resource $socket [, int $backlog]): bool
    Explication de la syntaxe
    socket_create
    socket_accept(resource $socket): resource|false
      domain spécifie le protocole utilisé par le socket actuel. Les protocoles disponibles sont les suivants :
      Domain
      Protocole réseau IPv4, TCP et UDP peuvent utiliser ce protocole🎜🎜🎜🎜AF_INET6🎜🎜Protocole réseau IPv6, TCP et UDP peuvent utiliser ce protocole🎜🎜🎜🎜AF_UNIX🎜🎜Protocole de communication local, avec de hautes performances et un faible coût IPC 🎜🎜🎜
      c Type Le type d'utilisateur précise le type de mot actuellement jet 🎜🎜🎜🎜🎜🎜Type🎜🎜 décrire 🎜🎜🎜🎜🎜🎜Sock_stream🎜🎜 peut être séquencé Un flux d'octets fiable, en duplex intégral, basé sur des liaisons, qui prend en charge les mécanismes de contrôle du flux de transfert de données. Le protocole TCP est basé sur ce socket de streaming. 🎜🎜🎜🎜SOCK_DGRAM🎜🎜Prise en charge des messages de données (sans connexion, peu fiable, longueur maximale fixe) Le protocole UDP est basé sur ce socket de message🎜🎜🎜🎜SOCK_SEQPACKET🎜🎜Données séquentielles, fiables, doubles industrielles, orientées connexion, de longueur maximale fixe communication, l'extrémité des données lit l'intégralité du paquet de données en recevant chaque segment de données 🎜🎜🎜🎜SOCK_RAW🎜🎜Lisez le protocole réseau d'origine, cette socket spéciale est disponible. Elle convient à la construction manuelle de tout type de protocole. Cette socket est généralement utilisée pour. implémenter les requêtes ICMP🎜🎜🎜🎜SOCK_RDM🎜🎜Couche de données fiable, mais l'ordre d'arrivée n'est pas garanti. Les systèmes d'exploitation généraux n'implémentent pas cette fonction🎜🎜🎜🎜.
    • protocol 设置指定 domain 套接字下的具体协议,如果所需协议是 TCP 或者 UDP,可以直接使用常量 SOL_TCPSOL_UDP,这个参数的具体值可通过 getprotobyname() 函数获取

    返回值

    socket_create() 正确时返回一个套接字资源,失败时返回 false。可以调用 socket_last_error() 获取错误码,错误码可以通过 socket_strerror(int $err_no) 转换为文字的错误说明。

    socket_bind

    socket_bind(resource $socket, string $address [, int $port]): bool

    绑定一个地址与端口到套接字

    参数:

    • socket 使用 socket_create() 创建的套接字资源

    • address

      如果套接字是 AF_INET 族,那么 address 必须是一个四点法的 IP 地址,例如 127.0.0.10.0.0.0

      如果套接字是 AF_UNIX 族,那么 address 是 Unix 套接字一部分(例如 /tmp/my.sock

    • port (可选)

      该参数仅用于使用 AF_INET 族时,指定当前套接字监听的端口号

    返回值:

    绑定成功返回 true,失败时则返回 false,同 socket_create ,在绑定失败时可以调用 socket_last_error() 获取错误码,错误码可以通过 socket_strerror(int $err_no) 转换为文字的错误说明。

    socket_listen

    socket_listen(resource $socket [, int $backlog]): bool

    在使用 socket_create() 创建套接字并使用 socket_bind() 将其绑定到名称之后,可能会告诉它侦听套接字上的传入连接。该函数仅适用于 SOCK_STREAMSOCK_SEQPACKET 类型的套接字。

    参数:

    • socket 使用 socket_create() 创建的套接字资源
    • backlog 最大数量的积压传入连接将排队等待处理,如果连接请求到达时队列已满,则客户端可能会收到指示为 ECONNREFUSED 的错误。或者,如果底层协议支持重传,则可能会忽略该请求,以便重试可能会成功。

    返回值:

    绑定成功返回 true,失败时则返回 false,可以调用 socket_last_error() 获取错误码,错误码可以通过 socket_strerror(int $err_no) 转换为文字的错误说明。

    socket_accept

    socket_accept(resource $socket): resource|false

    当有新的客户端连接时,返回一个新的 socket 资源以用于与客户端通信,如有多个连接排队,则返回第一个连接,相反如果没有待处理的连接,该函数会默认阻塞当前进程,直至新的客户端连接、断开

    参数:

    • socket 使用 socket_create() 创建的套接字资源

    返回值:

    成功时返回一个新的套接字资源,错误时返回 false,可以调用 socket_last_error() 获取错误码,错误码可以通过 socket_strerror(int $err_no) 转换为文字的错误说明。

    socket_connect

    socket_connect(resource $socket, string $address [, int $port = null]): bool

    使用套接字实例发起到 address 的连接

    参数:

    • socket 该参数必须是由 socket_create() 创建的 socket 实例

    • address

      如果套接字是 AF_INET 族,那么 address 必须是一个四点法的 IP 地址,例如 127.0.0.1 如果支持 IPv6 并且套接字是 AF_INET6,那么 address 也可以是一个有效的 IPv6 地址(例如 ::1

      如果套接字是 AF_UNIX 族,那么 address 是 Unix 套接字一部分(例如 /tmp/my.sock

    返回值:

    成功时返回 true, 或者在失败时返回 false

    socket_write

    socket_write(resource $socket, string $data [, int $length = null]): int|false

    传输数据至指定套接字

    参数:

    • socket 使用 socket_create()socket_accept() 创建的套接字资源

    • data 要发送的内容

    • length (可选)

      可以指定发送套接字的替代字节长度。如果这个长度大于实际发送内容的长度,它将被静默地截断为实际发送内容的长度。

    返回值:

    成功时返回成功发送的字节数,或者在失败时返回 false,可以调用 socket_last_error()socket_strerror(int $err_no) 获取具体错误信息

    socket_read

    socket_read(resource $socket, int $length, int $mode = PHP_BINARY_READ): string|false

    从套接字资源内读取数据

    参数:

    • socket 使用 socket_create()socket_accept() 创建的套接字资源(服务端为 socket_accept() 客户端为 socket_create()

    • length 指定最大能够读取的字节数。否则您可以使用 \r\n\0 结束读取(根据 mode 参数设置)

    • mode (可选)

      PHP_BINARY_READ (默认)- 使用系统的 recv() 函数。二进制安全地读取数据。

      PHP_NORMAL_READ - 读取到 \n\r 时停止。

    返回值:

    socket_read() 返回一个字符串,表示接收到的数据。如果发生了错误(包括远程主机关闭了连接),则返回 false,可以调用 socket_last_error()socket_strerror(int $err_no) 获取具体错误信息

    socket_close

    socket_close(resource $socket): void

    关闭并销毁一个套接字资源

    参数:

    • socket 使用 socket_create()socket_accept() 创建的套接字资源

    返回值:

    推荐学习:《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