> 백엔드 개발 > PHP 튜토리얼 > PHP 소켓 프로그래밍에서 일반적으로 사용되는 함수 및 간단한 c/s 상호 작용 구현

PHP 소켓 프로그래밍에서 일반적으로 사용되는 함수 및 간단한 c/s 상호 작용 구현

不言
풀어 주다: 2023-04-03 12:40:02
원래의
1652명이 탐색했습니다.

이 문서의 내용은 PHP 소켓 프로그래밍에서 일반적으로 사용되는 기능과 간단한 C/S 상호 작용의 구현에 대한 내용입니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

소켓 소개

소켓 공식 설명:
네트워크 프로그래밍에서 가장 일반적으로 사용되는 솔루션은 클라이언트/서버(클라이언트/서버) 모델입니다. 이 시나리오에서 클라이언트 응용 프로그램은 서버 프로그램에서 서비스를 요청합니다. 서비스 프로그램은 일반적으로 잘 알려진 주소에서 서비스에 대한 요청을 수신합니다. 즉, 서비스 프로세스는 클라이언트가 서비스 주소에 대한 연결 요청을 할 때까지 휴면 상태로 유지됩니다. 이 순간, 서비스 프로그램은 "활성화"되어 클라이언트에게 서비스를 제공하며 클라이언트의 요청에 적절하게 반응합니다. 이 클라이언트/서버 모델의 네트워크 프로그래밍을 용이하게 하기 위해 1990년대 초에 Microsoft와 다른 여러 회사는 WINDOWS에서 일련의 네트워크 프로그래밍 인터페이스, 즉 Windows 소켓 사양을 공동으로 개발했습니다. 이는 네트워크 프로토콜이 아니라 네트워크입니다. 프로그래밍 인터페이스. Windows에서 여러 프로토콜을 지원하는 개방형 네트워크 프로그래밍 인터페이스 집합입니다. 이제 Winsock은 기본적으로 프로토콜 독립적이 되었습니다. Winsock을 사용하여 여러 프로토콜의 기능을 호출할 수 있지만 TCP/IP 프로토콜이 더 일반적으로 사용됩니다. 소켓은 실제로 소켓 인터페이스가 있는 모든 컴퓨터와 통신할 수 있는 통신 포트를 컴퓨터에 제공합니다. 애플리케이션은 네트워크에서 전송하고 이 소켓 인터페이스를 통해 정보를 받습니다

소켓을 네트워크의 다양한 컴퓨터 애플리케이션을 연결할 수 있는 파이프라인으로 간단히 이해하고 파이프라인의 A 끝에서 많은 데이터를 전송할 수 있습니다. , 파이프의 B 끝에서 나옵니다(C, D, E, F... 끝에서도 나올 수 있음).

참고: 소켓 자체에는 실제 엔터티가 없으므로 소켓에 대한 개념만 알면 됩니다. 注意:我们会在不同语境下使用不同的词语去修饰 socket,你只需要对它有个概念就好了,因为 socket 本身就没有真正意义上的实体

Socket 函数介绍

Socket 通信依次会进行 Socket 创建、 Socket 绑定、Socket 监听、Socket 收发、Socket 关闭几个阶段,下面我们列举出 PHP 网络编程中最常用也是必不可少的几个常用的函数进行进一步的说明。

socket_create

TODO : 创建一个新的 socket 资源
函数原型: resource socket_create ( int $domain , int $type , int $protocol )
它包含三个参数,分别如下:

  • domain:AF_INET、AF_INET6、AF_UNIX,AF的释义就 address family,地址族的意思,我们常用的有 ipv4、ipv6

  • type: SOCK_STREAM、SOCK_DGRAM等,最常用的就是SOCK_STREAM,基于字节流的SOCKET类型,也是TCP协议使用的类型

  • protocol: SOL_TCP、SOL_UDP 这个就是具体使用的传输协议,一般可靠的传输我们选择 TCP,游戏数据传输我们一般选用 UDP 协议

socket_bind

TODO : 将创建的 socket 资源绑定到具体的 ip 地址和端口
函数原型: bool socket_bind ( resource $socket , string $address [, int $port = 0 ] )

它包含三个参数,分别如下:

  • socket: 使用socket_create创建的 socket 资源,可以认为是 socket 对应的 id

  • address: ip 地址

  • port: 监听的端口号,WEB 服务器默认80端口

socket_listen

TODO : 在具体的地址下监听 socket 资源的收发操作
函数原型: bool socket_listen ( resource $socket [, int $backlog = 0 ] )

它包含两个个参数,分别如下:

  • socket: 使用socket_create创建的socket资源

  • backlog: 等待处理连接队列的最大长度

socket_accept

TODO : 监听之后,接收一个即将来临的新的连接,如果连接建立成功,将返回一个新的 socket 句柄(你可以理解为子进程,通常父进程用来接收新的连接,子进程负责具体的通信)
函数原型: resource socket_accept ( resource $socket )

  • socket: 使用socket_create创建的socket资源

socket_write

TODO : 将指定的数据发送到 对应的 socket 管道
函数原型: int socket_write ( resource $socket , string $buffer [, int $length ] )

  • socket: 使用socket_create创建的socket资源

  • buffer: 写入到socket资源中的数据

  • length: 控制写入到socket资源中的buffer的长度,如果长度大于buffer的容量,则取buffer

    🎜소켓 기능 소개🎜🎜🎜소켓 통신은 소켓 생성, 소켓 바인딩, 소켓 모니터링, 소켓 보내기 및 받기, 소켓 닫기 등 여러 단계를 거쳐 진행됩니다. 아래에는 PHP 네트워크 프로그래밍에서 가장 일반적으로 사용되는 필수 기능이 나열되어 있습니다. 🎜

    socket_create

    🎜TODO: 새 소켓 리소스 만들기🎜함수 프로토타입: resource 소켓_create(int $domain, int $type, int $protocol)🎜각각 세 개의 매개 변수가 포함되어 있습니다. 🎜
    • 🎜domain: AF_INET, AF_INET6, AF_UNIX, AF의 의미는 주소 계열입니다. 주소 패밀리의 의미로 우리는 일반적으로 ipv4, ipv6🎜
    • 🎜type을 사용합니다: SOCK_STREAM, SOCK_DGRAM 등. 가장 일반적으로 사용되는 것은 SOCKET 유형 기반인 SOCK_STREAM입니다. 바이트 스트림에서 사용되는 TCP 프로토콜 유형🎜
    • 🎜프로토콜: SOL_TCP, SOL_UDP 일반적인 안정적인 전송을 위해 TCP를 선택합니다. 일반적으로 UDP 프로토콜을 선택합니다. 🎜
    • ul>

      socket_bind

      🎜TODO: 생성된 소켓 리소스를 특정 IP 주소 및 포트에 바인딩🎜Function 프로토타입: bool 소켓_bind(리소스 $socket, 문자열 $address [ , int $port = 0 ] )🎜🎜다음과 같은 세 개의 매개변수가 포함되어 있습니다.🎜
      • 🎜socket: socket_create 는 소켓🎜
      • 🎜address: ip address🎜
      • 🎜port: 수신 포트 번호, WEB 서버의 기본 포트에 해당하는 ID로 간주될 수 있습니다. 80🎜

      socket_listen

      🎜TODO: 특정 주소에서 소켓 리소스의 송수신 작업을 모니터링합니다.🎜함수 프로토타입: bool 소켓_listen(resource $socket [, int $backlog = 0 ] )🎜 🎜다음과 같은 두 개의 매개변수가 포함되어 있습니다: 🎜
      • 🎜socket: socket_create를 사용하여 생성된 소켓 리소스 >🎜
      • 🎜backlog: 처리를 기다리는 연결 대기열의 최대 길이🎜

      socket_accept

      🎜TODO: 청취 후 다가오는 새 메시지를 받습니다. 연결이 성공적으로 설정되면 새 소켓 핸들이 반환됩니다(자식 프로세스로 이해할 수 있으며 일반적으로 상위 프로세스는 새 연결을 수신하는 데 사용되며 하위 프로세스는 특정 통신을 담당합니다) 🎜기능 프로토타입: 리소스 소켓_accept(리소스 $socket )🎜
    • 🎜socket: socket_create🎜를 사용하여 생성된 소켓 리소스 li>

    socket_write

    🎜TODO: 지정된 데이터를 해당 소켓 파이프로 보냅니다.🎜함수 프로토타입: int 소켓_write(resource $socket, string $buffer [, int $length ] ) 🎜
    • 🎜socket: socket_create🎜
    • 🎜buffer: 작성된 데이터를 사용하여 생성된 소켓 리소스 소켓 리소스🎜
    • 🎜length: 소켓 리소스에 기록된 버퍼의 길이를 제어합니다. 버퍼의 용량보다 크면 버퍼의 용량🎜

    socket_read

    TODO: 전송된 데이터 가져오기
    함수 프로토타입: int 소켓_read(리소스 $socket , int $length )int socket_read ( resource $socket ,  int $length )

    • socket: 使用socket_create创建的socket资源

    • length: socket资源中的buffer的长度

    socket_close

    TODO : 关闭 socket 资源
    函数原型: void socket_close ( resource $socket )

    • socket: socket_accept或者socket_create产生的资源,不能用于stream资源的关闭

    stream_socket_server

    由于创建一个SOCKET的流程总是 socket、bind、listen,所以PHP提供了一个非常方便的函数一次性创建、绑定端口、监听端口

    函数原型: resource stream_socket_server ( string $local_socket [, int &$errno [, string &$errstr [, int $flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN [, resource $context ]]]] )

    • local_socket: 协议名://地址:端口号

    • errno: 错误码

    • errstr:  错误信息

    • flags: 只使用该函数的部分功能

    • context: 使用stream_context_create函数创建的资源流上下文

    socket 实现 C/S 交互

    基于上面的函数我们可以很方便的去构建 socket 通信程序(在这里我希望读者能单独建立一个目录比如socket 因为后续我们还会建立很多文件)我们先编辑一个服务端程序 server.php,如下:

    <?php date_default_timezone_set("Asia/Shanghai");
    error_reporting(E_NOTICE );
    
    /*  确保在连接客户端时不会超时   */
    set_time_limit(0);
    
    $ip = &#39;127.0.0.1&#39;;
    $port = 8090;
    
    /*
     +-------------------------------
     *    @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() Why failure is:".socket_strerror($sock)."\n";
    }
    
    if(($ret = socket_bind($sock,$ip,$port)) < 0) {
        echo "socket_bind() Why failure is:".socket_strerror($ret)."\n";
    }
    
    if(($ret = socket_listen($sock,4)) < 0) {
        echo "socket_listen() Why failure is:".socket_strerror($ret)."\n";
    }
    
    echo "Start time:".date(&#39;Y-m-d H:i:s&#39;) . PHP_EOL;
    echo "Listening at ".$ip.&#39;:&#39;.$port.PHP_EOL;
    
    
    do {
        /*  创建新的连接  */
        if (($msgsock = socket_accept($sock)) < 0) {
            echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
            break;
        } else {
            
        # 连接成功输出 Socket id
        $i = (int)$msgsock;
        echo "welcome client $i";
    
            # 向客户端通信(反馈)
            $msg ="连接成功!\n";
            socket_write($msgsock, $msg, strlen($msg));
        }
        socket_close($msgsock);
    } while (true);
    socket_close($sock);
    ?>
    로그인 후 복사

    再编辑一个客户端程序client.php,如下:

    <?php set_time_limit(0);
    $port = 8090;
    $ip = "127.0.0.1";
    
    /*
     +-------------------------------
     *    客户端 socket 连接整个过程
     +-------------------------------
     *    @socket_create
     *    @socket_connect
     *    @socket_write
     *    @socket_read
     *    @socket_close
     +--------------------------------
     */
    
    
    /**
     * @socket_connect:客户端发起套接字连接
     * @param socket  resource $socket       创建的$socket资源
     * @param address string   SOCK_STREAM   IP地址|Unix套接字
     * @param port    int                    端口
     */
    
    /**
     * @socket_create:创建并返回一个套接字
     * @param domain   string AF_INET         IPV4 网络协议
     * @param type     string SOCK_STREAM     全双工字节流(可用的套接字类型)
     * @param protocol string SOL_TCP         具体协议(IPV4下的TCP协议)
     * @param return   套接字
     */
    
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    if ($socket < 0) {
        echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n";
    }else {
        echo "try to connect &#39;$ip&#39; port: &#39;$port&#39;...\n";
    }
    
    
    $result = socket_connect($socket, $ip, $port);  #socket_connect的返回值应该是boolean值
    if ($result < 0) {
        echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
    }else {
        # 连接成功输出提示信息
        echo "connect successfully\n";
    
        # 向服务端发送数据
        socket_write($socket, " hello ", 1024);
    
        # 获取服务端数据
        $result = socket_read($socket, 1024);
        echo "服务器回传数据为:" . $result;
    
    
        echo "CLOSE SOCKET...\n";
        socket_close($socket);
        echo "CLOSE OK\n";    
        
    }
    
    
    
    ?>
    로그인 후 복사

    然后我们打开终端(命令行)进入文件目录下依次执行:

    php server.php
    php client.php
    로그인 후 복사

    运行效果如下:

    PHP 소켓 프로그래밍에서 일반적으로 사용되는 함수 및 간단한 c/s 상호 작용 구현

    注意

    • socket: socket_create

    • length: socket 리소스

      에 있는 버퍼의 길이를 사용하여 생성된 소켓 리소스 socket_close
      TODO: 소켓 리소스 닫기
      함수 프로토타입: void 소켓_close(리소스 $socket )
      • 🎜socket: 소켓_accept code> 또는 <code>socket_create에 의해 생성된 리소스는 stream 리소스🎜🎜🎜🎜stream_socket_server🎜🎜SOCKET 생성 프로세스가 항상 소켓이므로 닫는 데 사용할 수 없습니다. 따라서 PHP는 포트 생성, 바인딩, 포트 수신을 한 번에 할 수 있는 매우 편리한 기능을 제공합니다🎜🎜함수 프로토타입: resource stream_socket_server ( string $local_socket [, int &$errno [, string & $errstr [, int $flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN [, 리소스 $context ]]]] )🎜
        • 🎜local_socket: 프로토콜 이름://address :port number🎜🎜
        • 🎜errno: 오류 코드🎜🎜
        • 🎜errstr: 오류 메시지🎜🎜
        • 🎜flags: 이 함수의 일부만 사용🎜🎜
        • 🎜context: stream_context_create
        함수 리소스 흐름 컨텍스트🎜🎜🎜

        소켓은 C/S 상호작용을 구현합니다

        🎜위 함수를 기반으로, 우리는 쉽게 소켓 통신 프로그램을 만들 수 있습니다. (여기서 우리는 나중에 많은 파일을 생성할 것이기 때문에 독자들이 socket과 같은 별도의 디렉토리를 생성할 수 있기를 바랍니다.) 먼저 서버 프로그램 server.php는 다음과 같습니다.🎜rrreee🎜클라이언트 프로그램 <code>client.php를 다음과 같이 편집합니다.🎜rrreee🎜그런 다음 터미널(명령줄)을 열고 순서대로 실행할 파일 디렉터리를 입력합니다.🎜 rrreee🎜실행 효과는 다음과 같습니다.🎜🎜  PHP 소켓 프로그래밍에서 일반적으로 사용되는 함수 및 간단한 c/s 상호 작용 구현🎜🎜참고 서버가 수신 대기 중인 경우 프로세스가 일시 중지되고 다른 작업을 수행할 수 없습니다. . 클라이언트 프로그램을 실행하려면 다른 터미널을 시작해야 할 수도 있습니다🎜🎜관련 권장 사항: 🎜🎜🎜PHP와 MySql은 어떻게 백그라운드 데이터 읽기를 인식합니까?(코드) 🎜🎜🎜thinkphp5는 작업자 타이머를 사용하여 사이트 콘텐츠 코드를 정기적으로 크롤링합니다 🎜🎜 🎜🎜

위 내용은 PHP 소켓 프로그래밍에서 일반적으로 사용되는 함수 및 간단한 c/s 상호 작용 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿