ホームページ  >  記事  >  バックエンド開発  >  PHPでのソケットの使い方を詳しく解説

PHPでのソケットの使い方を詳しく解説

墨辰丷
墨辰丷オリジナル
2018-05-30 16:09:512142ブラウズ

ソケットの本来の英語の意味は「穴」または「ソケット」です。 BSD UNIX のプロセス通信機構としては後者の意味をとります。 IP アドレスとポートを記述するために使用され、通信チェーンへのハンドルです。インターネット上のホストは通常​​、複数のサービス ソフトウェアを実行し、複数のサービスを同時に提供します。各サービスはソケットを開き、それをポートにバインドします。異なるポートは異なるサービスに対応します。ただし、理解する必要があるのは、いくつかのソケット関数間の関係と、それらが果たす役割だけです。著者の意見では、ソケット プログラミングは実際にはネットワーク サービスのクライアントとサーバーを確立するものであり、クライアントとサーバーの内容を理解していれば、これは mysql のクライアントとサーバーと同じです。 mysql のサーバーについて説明すれば、これから説明する内容が理解できるはずです。

TCP、UDP、ソケットスリーウェイハンドシェイクなど、ソケットプログラミングに関連するネットワークプロトコルについては、インターネット上に非常に詳細な説明がありますので、ここでは説明しません。ソケットを確立するプロセスのスクリーンショットを撮ってください:

この写真は、一生懸命誰かから盗んだものです、同時に、あなたもよく見てください。スクリーンショットを盗まれた作者に感謝の意を表したいと思います。パターンを盗用したことをお詫びします。気にしないでください。絵を描くのがめんどくさい(というか絵に自信がないということです笑)。

ソケットはどのように接続を確立するのでしょうか?上で述べたように、接続を確立するプロセスは、mysql クライアントとサーバー間の接続と基本的に同じです。 mysql との違いは、mysql のサーバーとクライアントが編集されており、それを適用するだけでよいということです。しかし、重大な瞬間が来ました。Socket が提供するのは、数十のソケット機能だけです。

これが意味するのは、ソケットプログラミングではサーバーとクライアントを自分で作成する必要がある、つまり「ソケットプログラミング」、つまりmysqlに似たサーバーとクライアントのアプリケーションを構築する必要があるということです。

そうは言っても、お聞きしたいのですが、このソケットは頭痛を引き起こすと思いますか?適用するサーバーもクライアントも作成しません。ソケット関数を使用して、独自のネットワーク プロトコル ソケット アプリケーションを作成する必要があります。独自のアプリケーションが必要な場合でも、ソケットを扱う必要があります。あはは、これは単なる余談ですので、多くは言いませんが、本題に入りましょう。

ソケットプログラミングに混乱する前に、ソケットのいくつかの主要な機能を見て、それぞれの機能を最初に説明します。そうしないと、ソケット プログラミングの基礎がまったくない人がこれを読むと、読み終わった後、この記事を思い切って読み飛ばして、今後ソケット恐怖症になってしまうのではないかと思います。ハハ、もっと言いました。

ソケットのキー関数1:

socket_create($netパラメータ1, $streamパラメータ2, $protocolパラメータ3)

機能: 端的に言えば、ソケットソケットを作成します。

戻り値: ソケット、または false、パラメータが間違っている場合は E_WARNING 警告が発行されます

PHP オンラインマニュアルでは、より明確に説明されています:

socket_create は、通信ノードとも呼ばれるソケットを作成して返します。一般的なネットワーク接続は 2 つのソケットで構成され、1 つはクライアント側で実行され、もう 1 つはサーバー側で実行されます。

上記の文はphpオンラインマニュアルからコピーしました。ここでの意味は、上で繰り返し述べたクライアントとサーバーとまったく同じであることがわかりましたか?ふふ。

パラメータ1は:ネットワークプロトコル、

ネットワークプロトコルとは何ですか?オプションは以下の3つです:

AF_INET: IPv4ネットワークプロトコル。 TCP と UDP の両方がこのプロトコルを使用できます。これは一般的に使用されます。

AF_INET6: IPv6 ネットワークプロトコル。 TCP と UDP の両方がこのプロトコルを使用できます。

AF_UNIX: ローカル通信プロトコル。高性能かつ低コストの IPC (プロセス間通信)。

パラメータ2:ソケットストリーム、オプションは:

SOCK_STREAM SOCK_DGRAM SOCK_SEQPACKET SOCK_RAW SOCK_RDM。

ここでは最初の 2 つだけを説明します:

SOCK_STREAM TCP プロトコルソケット。

SOCK_DGRAM UDPプロトコルソケット。

詳細については、こちらのリンクを参照してください: http://php.net/manual/zh/function.socket-create.php

パラメータ 3: プロトコル プロトコル、オプションは:

SOL_TCP: TCP プロトコル。

SOL_UDP: UDPプロトコル。

ここから、socket_create関数の第2パラメータと第3パラメータが実は関連していることが分かります。

例えば、最初のパラメータが IPv4 プロトコル: AF_INET を使用し、次に 2 番目のパラメータが TCP ソケット: SOCK_STREAM を使用する場合、

3 番目のパラメータは SOL_TCP を使用する必要がありますが、これは理解するのが難しくありません。

TCPプロトコルソケット、当然TCPプロトコルしか使えませんよね? UDP ソケットを使用する場合、3 番目のパラメータの選択方法については説明しません (笑)。

キー関数2:

socket_connect($socketパラメータ1, $ipパラメータ2, $portパラメータ3)

関数:ソケットを接続、戻り値はtrueかfalseです

パラメータ1:socket_createの関数の戻り値

3: ポート番号

× キー関数 3:

×ソケットバインド($socket パラメータ 1, $ip パラメータ 2, $port パラメータ 3)

× 機能:ソケットをバインドし、戻り値はtrueかfalseです

パラメータ1:socket_createの関数戻り値

パラメータ2:ipアドレス

パラメータ3:ポート番号

キー関数4:

socket_listen($socketパラメータ1, $backlog パラメータ 2 )

関数: ソケットを監視し、戻り値は true または false

パラメータ 1:socket_create の関数の戻り値

パラメータ 2: 待機ソケットの最大数

キー関数 5:

socket_accept( $socket)

関数:ソケットリソース情報を受信、ソケット情報リソースを正常に返却、失敗はfalse

パラメータ:socket_createの関数戻り値

キー関数6:

socket_read($socketパラメータ1, $lengthパラメータ2 )

関数:ソケットのリソース情報を読み込み、

戻り値:ソケットリソースの文字列情報への変換に成功、失敗はfalse

パラメータ1:socket_createまたはsocket_acceptの関数戻り値

パラメータ2:長さ読み込んだ文字列のバイト長

キー関数7:

socket_write($socketパラメータ1, $msgパラメータ2, $strlenパラメータ3)

機能:ソケットにデータを書き込む

戻り値:文字列のバイト長を返すことに成功しました。文字列、失敗はfalse

パラメータ1:socket_createまたはsocket_acceptの関数戻り値

in in in on in in ining can in :

Socket_Close ($ Socket)

: セットピースを閉じる

戻り値:正常に TRUE、False に戻ります

パラメータ: Socket_create または Socket_accept 、より重要な 2 つの関数を以下に示します

socket_last_error($socket)、パラメータはsocket_createの戻り値で、その関数は最後のエラーコード番号を取得することです。ソケット、戻り値はソケットコード

socket_strerror($code )、パラメータはsocket_last_error関数の戻り値、コードの文字列情報が取得されます。ソケットプログラミングでは、これらの 2 つの関数は依然として非常に重要です。特に初心者にとっては、これを使用する必要があると思います。私のコメントをよく読んでください。コメントは非常に重要です。笑。

サーバーサイドスクリプト、D:vhosttestsocketserver_socket.php

<?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);

socket_bindのover through forward 、socket_listen関数とsocket_accept関数を実行した後のみ、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);//工作完毕,关闭套接流

これら 2 つのスクリプトをテストするにはどうすればよいでしょうか?

まず Windows DOS ウィンドウ、つまり cmd の黒いウィンドウを開いてから、php D:vhosttestsocketserver_socket.php,を実行します

サーバー側の黒いウィンドウを実行し続けます

次に、PHP クライアントスクリプトを実行できますブラウザ経由で、別の cmd black window を開いて

php D:vhosttestsocketclient_socket.php

ここで注意してください: 追加方法がわからない場合は、php 実行名を Windows 環境変数に追加する必要があります。それ、

php実行コマンドを入力してください 絶対コマンドでディレクトリを実行するか、Baiduの環境変数にphpコマンドを追加することもできます

これは私の状況です、あなたのファイルアドレスは私のものと異なる可能性があります、に従って操作してくださいあなたの住所に送ってください。そうしないと、結果はあなたが責任を負います、笑

上で述べたように、ソケットプログラミングではサーバーとの通信が必要なので、サーバー上の黒いウィンドウを開いたままにしておく必要があります。

追記:

socket_set_option($socket パラメータ 1, $level パラメータ 2, $optname パラメータ 3, $optval パラメータ 4)

この関数の機能は、ソケットのデータ フロー オプションを設定することですが、これはまだ非常に複雑です重要な機能。 Parameter 1:socket_createまたはsocket_accept

parameter2の関数戻り値:

SO_REUSEADDR ソケットポートが解放された直後に再度使用できるようにするためです

パラメータ3がこれであれば、パラメータ4はtrueかfalseになります

SO_RCVTIMEO ソケットが受信するまでの最大タイムアウト時間ですリソース

SO_SNDTIMEO ソケットの送信リソースの最大タイムアウトです

パラメータ3がこの2つの場合、パラメータ4はこのような配列になります('sec'=>1,'usec'=>500000)

タイムアウトを設定するための最大時間は配列で設定されていますが、一方は秒単位、もう一方はマイクロ秒単位で、効果は同じです

以上がこの記事の全内容です、そうなると幸いですみんなの学習に役立ちます。


関連する推奨事項:

PHPでよく使用されるマジックメソッドの詳細な説明


PHPでCookieを使用する方法の詳細な説明

中国語の文字化けを解決するPHPメソッド


以上がPHPでのソケットの使い方を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。