>백엔드 개발 >PHP 튜토리얼 >PHP의 소켓 프로그래밍에 대한 자세한 설명

PHP의 소켓 프로그래밍에 대한 자세한 설명

高洛峰
高洛峰원래의
2016-12-12 09:41:191409검색

PHP 소켓 프로그래밍은 상대적으로 이해하기 어렵습니다. 그러나 소켓 기능과 그들이 수행하는 역할 간의 관계를 이해하는 한 저자의 의견으로는 소켓 프로그래밍은 실제로 이해하기 어렵지 않습니다. 네트워크 서비스 클라이언트 및 서버. 이는 mysql 클라이언트 및 서버와 동일합니다. mysql 클라이언트 및 서버가 무엇인지 이해했다면 제가 이야기하려는 내용을 이해할 수 있을 것입니다.

TCP, UDP, 소켓 3방향 핸드셰이크 등과 같은 소켓 프로그래밍과 관련된 네트워크 프로토콜에 대해서는 인터넷에 이러한 네트워크 프로토콜에 대한 매우 자세한 설명이 있으므로 여기서는 다루지 않겠습니다. 소켓을 잘라서 소켓을 만들겠습니다. 과정 사진을 보시죠:

PHP의 소켓 프로그래밍에 대한 자세한 설명

이 사진은 다른 분께서 열심히 찍어 주셔야 합니다. 잘 보세요. 동시에 저에게서 스크린샷을 훔친 작가에게도 감사의 말씀을 전하고 싶습니다. 걱정하지 않으셨으면 좋겠습니다. 저는 그림을 그리는 게 너무 게으른 편이에요(사실 그림 실력에 자신이 없다는 뜻이죠, 하하).

소켓은 어떻게 연결을 설정하나요? 위에서 언급했듯이 연결을 설정하는 과정은 본질적으로 mysql 클라이언트와 서버 간의 연결과 동일합니다. 그것과 mysql의 차이점은 mysql의 서버와 클라이언트가 우리를 위해 편집되었기 때문에 그것을 적용하기만 하면 된다는 것입니다. 그러나 중요한 순간이 왔습니다. 소켓은 우리에게 아무것도 제공하지 않습니다. 소켓이 제공하는 유일한 것은 수십 개의 소켓 기능입니다.

이는 소켓 프로그래밍을 위해서는 서버와 클라이언트를 직접 생성해야 한다는 의미입니다. 즉, ``소켓 프로그래밍``은 mysql 터미널 애플리케이션과 유사한 서버 및 클라이언트를 생성해야 한다는 의미입니다.

그러고보니 묻고 싶은게 이 소켓이 머리 아프다고 생각하시나요? 우리가 적용할 서버나 클라이언트를 생성하지도 않습니다. 우리가 직접 소켓 기능을 사용하고 자체 네트워크 프로토콜 소켓 애플리케이션을 생성해야 합니다. 이것이 머리가 아프지 않습니까? 자신만의 애플리케이션이 필요한 경우에는 여전히 소켓을 처리해야 합니다. 하하, 이건 그냥 여담이에요. 많이 말하지 않겠습니다. 요점만 말씀드리겠습니다.

소켓 프로그래밍에 헷갈리기 전에 소켓의 몇 가지 주요 기능을 살펴보고 각각의 기능에 대해 설명하겠습니다. 그렇지 않고, 소켓 프로그래밍에 대한 기초가 전혀 없는 사람이 이 글을 읽는다면, 이 글을 읽고 나서 과감히 이 글을 스킵하고 앞으로 소켓에 대한 공포증이 생길까 두렵습니다. 하하, 제가 더 말했어요.

  소켓의 주요 기능 1:

 socket_create($net 매개변수 1, $stream 매개변수 2, $protocol 매개변수 3)

  기능: 소켓 소켓을 생성하고, 솔직하게 말하면 네트워크 데이터 흐름입니다.

반환 값: 소켓 또는 false, 매개변수 오류에 대해 E_WARNING 경고가 발행됩니다.

PHP 온라인 설명서에 더 명확하게 설명되어 있습니다.

소켓_create가 소켓을 생성하고 반환합니다. 통신 노드라고도 합니다. 일반적인 네트워크 연결은 2개의 소켓으로 구성됩니다. 하나는 클라이언트 측에서 실행되고 다른 하나는 서버 측에서 실행됩니다.

위 문장은 PHP 온라인 매뉴얼에서 복사한 것입니다. 여기서의 의미가 위에서 반복적으로 언급한 클라이언트 및 서버와 완전히 동일하다는 것을 알 수 있습니까? 헤헤.

 매개변수 1은 네트워크 프로토콜,

 네트워크 프로토콜은 무엇인가요? 옵션은 다음 세 가지입니다.

 AF_INET: IPv4 네트워크 프로토콜입니다. TCP와 UDP 모두 이 프로토콜을 사용할 수 있습니다. 이것은 일반적으로 사용됩니다.

 AF_INET6: IPv6 네트워크 프로토콜입니다. TCP와 UDP 모두 이 프로토콜을 사용할 수 있습니다.

 AF_UNIX: 로컬 통신 프로토콜입니다. 고성능 및 저비용 IPC(프로세스 간 통신).

매개변수 2: 소켓 스트림, 옵션은 다음과 같습니다.

SOCK_STREAM SOCK_DGRAM SOCK_SEQPACKET SOCK_RAW SOCK_RDM.

여기서는 처음 두 개만 설명합니다:

SOCK_STREAM TCP 프로토콜 소켓.

SOCK_DGRAM UDP 프로토콜 소켓.

자세한 내용은 여기 링크를 참조하세요: http://php.net/manual/zh/function.socket-create.php

매개변수 3: 프로토콜, 옵션은 다음과 같습니다.

SOL_TCP: TCP 프로토콜입니다.

SOL_UDP: UDP 프로토콜입니다.

여기서 보면 실제로는 Socket_create 함수의 두 번째 매개변수와 세 번째 매개변수가 연관되어 있음을 알 수 있다.

예를 들어 첫 번째 매개변수가 IPv4 프로토콜인 AF_INET을 사용하고 두 번째 매개변수가 TCP 소켓인 SOCK_STREAM을 사용하는 경우

세 번째 매개변수는 SOL_TCP를 사용해야 합니다. 이해하기 어려울 것입니다.

TCP 프로토콜 소켓은 당연히 TCP 프로토콜만 사용할 수 있겠죠? UDP 소켓을 사용하는 경우 세 번째 매개변수를 선택하는 방법은 말하지 않겠습니다. 하하.

키 기능 2:

소켓_connect($socket 매개변수 1, $ip 매개변수 2, $port 매개변수 3)

기능: 소켓을 연결하면 반환 값은 true입니다. 또는 false

 매개변수 1: 소켓_create의 함수 반환 값

 매개변수 2: IP 주소

 매개변수 3: 포트 번호

 주요 기능 3:

  socket_bind($socket 매개변수 1, $ip 매개변수 2, $port 매개변수 3)

  기능: 소켓 바인딩, 반환 값은 true 또는 false입니다

   매개변수 1: 기능 소켓_create 반환 값

매개변수 2: IP 주소

매개변수 3: 포트 번호

키 기능 4:

소켓_listen($socket 매개변수 1,$ backlog 매개변수 2)

함수: 소켓을 수신합니다. 반환 값은 true 또는 false입니다.

매개변수 1: 소켓_create의 함수 반환 값

매개변수 2: 최대 개수 of listening 소켓

주요 기능 5:

소켓_accept($socket)

기능: 소켓의 자원 정보를 수신하고 소켓을 성공적으로 반환합니다. 정보 자원, 실패는 false입니다.

매개변수: 소켓_create의 함수 반환 값

키 기능 6:

소켓_read($socket 매개변수 1, $length 매개변수 2)

기능: 읽기 소켓의 리소스 정보,

반환 값: 소켓 리소스를 문자열 정보로 성공적으로 변환, 실패는 false

매개변수 1: 소켓_create 또는 소켓_accept의 함수 반환 값

매개변수 2: 읽은 문자열의 길이

키 기능 7:

소켓_write($socket 매개변수 1, $msg 매개변수 2, $ strlen 매개변수 3)

기능 : 소켓에 데이터 쓰기

반환 값: 성공하면 문자열의 바이트 길이를 반환하고 실패하면 false

매개변수 1: 소켓_create 또는 소켓_accept의 함수 반환 값

매개변수 2: 문자열

매개변수 3: 문자열 길이

키 기능 8:

소켓_close($ 소켓)

기능: 닫기 소켓

반환 값: 성공 시 true, 실패 시 false

매개변수: 소켓_create 또는 소켓_accept 함수 반환 값

아래 8가지 함수는 소켓의 핵심 함수입니다. 두 가지 더 중요한 함수

Socket_last_error($socket). 매개변수는 소켓_create의 반환 값입니다. 해당 기능은 소켓의 마지막 오류 코드, 반환 값 소켓 코드를 가져오는 것입니다.

소켓_strerror($code), 매개변수는 소켓_last_error 함수의 반환 값이며, 코드의 문자열 정보를 가져오고, 반환 값은 소켓의 오류 메시지입니다

이 두 함수는 소켓에서 여전히 매우 중요합니다. 프로그래밍을 작성할 때 특히 초보자의 경우 디버깅에 사용할 수 있어야 한다고 생각합니다.

이것이 코드입니다. 주의하세요. 내 의견을 주의 깊게 읽어보세요. 중요하다, 댓글은 매우 중요하다, 댓글은 매우 중요하다, 중요한 것은 세 번 외쳐야 한다, 하하.

서버 스크립트, D:vhosttestsocketserver_socket.php

팁: 위의 세 가지 기능인 소켓_bind, 소켓_listen 및 소켓_accept의 실행 순서는 변경할 수 없습니다. 즉,
<?php
//创建服务端的socket套接流,net协议为IPv4,protocol协议为TCP
$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);

  /*绑定接收的套接流主机和端口,与客户端相对应*/
  if(socket_bind($socket,&#39;127.0.0.1&#39;,8888) == false){
    echo &#39;server bind fail:&#39;.socket_strerror(socket_last_error());
    /*这里的127.0.0.1是在本地主机测试,你如果有多台电脑,可以写IP地址*/
  }
  //监听套接流
  if(socket_listen($socket,4)==false){
    echo &#39;server listen fail:&#39;.socket_strerror(socket_last_error());
  }
//让服务器无限获取客户端传过来的信息
do{
  /*接收客户端传过来的信息*/
  $accept_resource = socket_accept($socket);
  /*socket_accept的作用就是接受socket_bind()所绑定的主机发过来的套接流*/

  if($accept_resource !== false){
    /*读取客户端传过来的资源,并转化为字符串*/
    $string = socket_read($accept_resource,1024);
    /*socket_read的作用就是读出socket_accept()的资源并把它转化为字符串*/

    echo &#39;server receive is :&#39;.$string.PHP_EOL;//PHP_EOL为php的换行预定义常量
    if($string != false){
      $return_client = &#39;server receive is : &#39;.$string.PHP_EOL;
      /*向socket_accept的套接流写入信息,也就是回馈信息给socket_bind()所绑定的主机客户端*/
      socket_write($accept_resource,$return_client,strlen($return_client));
      /*socket_write的作用是向socket_create的套接流写入信息,或者向socket_accept的套接流写入信息*/
    }else{
      echo &#39;socket_read is fail&#39;;
    }
  /*socket_close的作用是关闭socket_create()或者socket_accept()所建立的套接流*/
    socket_close($accept_resource);
  }
}while(true);
socket_close($socket);

먼저 소켓_바인딩을 실행한 다음, 소켓_청취, 마지막으로 소켓_accept를 실행해야 합니다.

클라이언트 스크립트, D: vhosttestsocketclient_socket.php

이 두 스크립트를 테스트하는 방법은 무엇입니까?
<?php
  //创建一个socket套接流
  $socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
  /****************设置socket连接选项,这两个步骤你可以省略*************/
   //接收套接流的最大超时时间1秒,后面是微秒单位超时时间,设置为零,表示不管它
  socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 1, "usec" => 0));
   //发送套接流的最大超时时间为6秒
  socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array("sec" => 6, "usec" => 0));
  /****************设置socket连接选项,这两个步骤你可以省略*************/

  //连接服务端的套接流,这一步就是使客户端与服务器端的套接流建立联系
  if(socket_connect($socket,&#39;127.0.0.1&#39;,8888) == false){
    echo &#39;connect fail massege:&#39;.socket_strerror(socket_last_error());
  }else{
    $message = &#39;l love you 我爱你 socket&#39;;
    //转为GBK编码,处理乱码问题,这要看你的编码情况而定,每个人的编码都不同
    $message = mb_convert_encoding($message,&#39;GBK&#39;,&#39;UTF-8&#39;);
    //向服务端写入字符串信息

    if(socket_write($socket,$message,strlen($message)) == false){
      echo &#39;fail to write&#39;.socket_strerror(socket_last_error());

    }else{
      echo &#39;client write success&#39;.PHP_EOL;
      //读取服务端返回来的套接流信息
      while($callback = socket_read($socket,1024)){
        echo &#39;server return message is:&#39;.PHP_EOL.$callback;
      }
    }
  }
  socket_close($socket);//工作完毕,关闭套接流

먼저 cmd 블랙창인 윈도우의 도스창을 열고, php D:vhosttestsocketserver_socket.php를 실행시켜주세요,

서버의 블랙창이 계속 실행되게 해주세요,

둘째, PHP 클라이언트 스크립트는 브라우저를 통해 실행하거나 cmd 검정 창을 열어서 실행할 수 있습니다.

 php D:vhosttestsocketclient_socket.php

여기를 참고하세요: php 실행 이름은 꼭 윈도우 환경변수에 추가해주세요. 추가방법을 모르신다면

php 실행명령어 디렉토리에 들어가서 절대명령어로 실행해 주세요. Baidu의 환경 변수에 php 명령을 추가할 수도 있습니다

여기 내 상황이 있습니다. 파일 주소가 내 파일 주소와 다를 수 있습니다. 주소 상황에 따라 작업하십시오. 그렇지 않으면 결과에 대한 책임은 귀하에게 있습니다. ㅎㅎ ​​

위에서 말한 것처럼 소켓 프로그래밍은 서버가 있어야 통신이 가능하기 때문에 서버의 검은 창은 항상 열어두어야 합니다.

포스트스크립트:

socket_set_option($socket 매개변수 1, $level 매개변수 2, $optname 매개변수 3, $optval 매개변수 4)

이 함수의 기능은 다음과 같습니다. 인터페이스는 매우 중요한 기능인 데이터 흐름 옵션을 설정합니다.

매개변수 1:socket_create또는socket_accept의 함수 반환 값

매개변수 2:SOL_SOCKET, 이 옵션이 유일한 것 같습니다.

매개변수 3은 매개변수 4와 관련되어 있습니다.

매개변수 3은 다음과 같습니다: SO_REUSEADDR SO_RCVTIMEO S0_SNDTIMEO

설명:

SO_REUSEADDR 소켓 포트가 해제된 후 즉시 다시 사용할 수 있습니다.

이 경우 매개변수 4는 true 또는 false일 수 있습니다

SO_RCVTIMEO  소켓의 수신 자원의 최대 타임아웃입니다

SO_SNDTIMEO  소켓의 송신 자원의 최대 타임아웃입니다

매개변수 3이 이 둘이면 매개변수 4는 다음과 같은 배열입니다('sec'=>1,'usec'=>500000)

배열은 다음과 같이 채워집니다. 최대 시간 초과 시간은 하나는 초 단위이고 다른 하나는 마이크로초 단위입니다. 효과는 동일합니다


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.