ホームページ  >  記事  >  バックエンド開発  >  PHP+Socketシリーズはクライアントとサーバー間のデータ転送を実現します

PHP+Socketシリーズはクライアントとサーバー間のデータ転送を実現します

藏色散人
藏色散人転載
2023-02-02 11:35:014970ブラウズ

この記事では、PHP ソケットに関する関連知識を提供します。主にソケットとは何か? について紹介します。 PHPソケットはどのようにしてクライアントとサーバー間のデータ送信を実現するのでしょうか?興味のある方は以下をご覧ください。皆様のお役に立てれば幸いです。

ソケットの概要

ネットワーク プロセス間の通信を実現するために、ほとんどすべてのアプリケーションはソケットを使用します。ソケットは、アプリケーション層と TCP/IP プロトコル ファミリの間の中間通信です。抽象化レイヤー。インターフェイスのセットです。設計モードでは、ソケットは実際にはファサード モードであり、複雑な TCP/IP プロトコル ファミリをソケット インターフェイスの背後に隠します。ユーザーにとっては、一連の単純なインターフェイスがすべてであり、ソケットが指定された仕様に準拠するようにデータを編成できるようになります。プロトコル

PHP+Socketシリーズはクライアントとサーバー間のデータ転送を実現します

ソケットの本来の意味は英語で「穴」「ソケット」ですが、一般に「ソケット」とも呼ばれ、IPアドレスやポートの表記に使用されます。通信チェーンのハンドルを使用して、異なる仮想マシンまたは異なるコンピュータ間の通信を実装できます。

ソケットリンクの 3 つのプロセス

  • サーバーリッスン: IP ポート番号

  • クライアントリクエスト: サービスエンド IP に送信し、ポート接続リクエスト

  • リンク確認: サーバーソケットはクライアントソケット接続リクエストをリッスンまたは受信し、新しいプロセスを作成します。サーバーソケットの説明をクライアントに送信します。クライアントのリクエスト。クライアントがこの説明を確認すると、接続が確立されます。サーバーのソケットは引き続き待機状態にあり、他のクライアント ソケットからの接続要求を受け入れ続けます。

PHP+Socketシリーズはクライアントとサーバー間のデータ転送を実現します

php はソケットを実装します

php でソケットを使用する必要がある場合は、コンパイル時に -- を追加する必要がありますphp enable-sockets 設定項目を有効にするには、php -m|grepソケット コマンドを使用して有効ステータスを確認できます。具体的なコンパイル プロセスについては、この記事#を参照してください。

##クイック エクスペリエンス

サーバーとクライアントの簡略化されたコードは次のとおりです。実行後、サーバーはブロックされ、クライアントの接続を待ちます。クライアントはコンソール上で入力コンテンツを要求します。入力後、情報はサービスに表示されます。クライアントは印刷し、クライアントは大文字に変換されたコンテンツを表示します。この例のサーバーとクライアントは同じサーバー上で実行されます:

サーバーリスニング

<?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
ソケット リソース (通常は通信ノードとも呼ばれます) を作成して返します。一般的なソケットは少なくとも 2 つのソケットで構成され、1 つはクライアント側で実行され、もう 1 つはサーバー側で実行されます。

パラメータ:

    ##domain
  • 現在のソケットが使用するプロトコルを指定します。使用可能なプロトコルは次のとおりです:

    ドメイン説明AF_INETIPv4 ネットワーク プロトコル、TCP と UDP の両方このプロトコルを使用しますAF_INET6IPv6 ネットワーク プロトコル、TCP と UDP の両方がこのプロトコルを使用できますAF_UNIX高性能かつ低コストのローカル通信プロトコル、IPC
    ##type
  • ユーザーが現在の通信プロトコルを指定します。 set インターフェイスで使用されるタイプ
  • typeDescription SOCK_STREAM データ転送フロー制御メカニズムをサポートする、シーケンシャルで信頼性の高い全二重のリンクベースのバイト ストリーム。 TCP プロトコルは、このストリーミング ソケットに基づいています。 #SOCK_DGRAM データ メッセージ (コネクションレス、信頼性が低く、最大長が固定) のサポート UDP プロトコルは、このメッセージ ソケットに基づいていますSOCK_SEQPACKET シーケンシャル、信頼性の高い、全二重、コネクション型、固定最大長のデータ通信。データエンドは各データ セグメント パケットを受信することでデータ セグメント全体を読み取ります。 SOCK_RAWSOCK_RDM##
  • 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视频教程》                                                    

    元のネットワーク プロトコルを読み取ります。この特別なソケットを使用して、あらゆるタイプのプロトコルを手動で構築できます。通常、このソケットは ICMP リクエストの実装に使用されます
    信頼性の高いデータ層ですが、到着順序は保証されません。一般的なオペレーティング システムにはこの機能は実装されていません

以上がPHP+Socketシリーズはクライアントとサーバー間のデータ転送を実現しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlearnku.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。