phpのソケット
◆SocketベースPHPは、Berkleyのsocketライブラリを使用して接続を作成します.socketはデータ構造にすぎない.このsocketデータ構造を使用して、クライアントとサーバ間のセッションを開始します.このサーバは、新しいセッションを生成する準備をリスニングしています.クライアントがサーバに接続されると、サーバがリスニング中のポートを開いてセッションを行います.このとき,サーバ側がクライアントの接続要求を受け付けると,1回のループが行われる.このクライアントはサーバに情報を送信することができ,サーバもクライアントに情報を送信することができるようになった.Socketを生成するには、プロトコル、socketタイプ、共通プロトコルタイプの3つの変数が必要です.socketを生成するには、3つのプロトコルを選択し、次の内容を見て詳細なプロトコル内容を取得します.共通のプロトコル・タイプを定義するには、必須の要素を接続します.次の表では、共通のプロトコルタイプを見てみましょう.表1:プロトコル名/定数説明AF_INETこれは多くのsocketを生成するためのプロトコルであり、IPv 4のアドレスAF_で使用されるTCPまたはUDPを使用して伝送される.INET 6は上記と似ていますが、IPv 6のアドレスAF_に使用されます.UNIXローカルプロトコルは、UnixとLinuxシステムで使用され、あまり使用されません.一般的には、クライアントとサーバが同じマシンにいるときに表2を使用します.Socketタイプ名/定数記述SOCK_STREAMというプロトコルは,順序的で信頼性が高く,データが完全なバイトストリームベースの接続である.これは最も多くのsocketタイプを使用し、このsocketはTCPを使用して伝送されます.SOCK_DGRAMというプロトコルは、接続されていない固定長の伝送呼び出しである.このプロトコルは信頼性がなく、UDPを使用して接続されています.SOCK_SEQACK ETというプロトコルは2回線の信頼性の高い接続であり,固定長のパケットを送信して伝送する.読み取りを行うには、このパッケージを完全に受け入れなければなりません.SOCK_RAWというsocketタイプは、ICMP共通プロトコルを使用する単一のネットワークアクセスを提供します.(ping、tracerouteはこのプロトコルを使用する)SOCK_RDMというタイプはめったに使用されず、ほとんどのオペレーティングシステムでは実現されていない.これはデータリンク層に提供されて使用され、パケット順序表3を保証しない.共通プロトコル名/定数記述ICMPインターネット制御メッセージプロトコルは、主にゲートウェイとホスト上で使用され、ネットワークの状況を確認し、エラー情報を報告するために使用される.UDPユーザーデータメッセージプロトコルは、接続されていない、信頼できない伝送プロトコルTCP伝送制御プロトコルであり、最も多くの信頼性の高い共通プロトコルを使用しており、パケットが受信者に届くことを保証し、伝送中にエラーが発生した場合、エラーパケットを再送信します.socketを生成する3つの要素を知っていますphpでsocket_を使用しますcreate()関数を使用してsocketを生成します.このソケットcreate()関数には、1つのプロトコル、1つのsocketタイプ、1つの共通プロトコルの3つのパラメータが必要です.socket_create()関数の実行は、socketを含むリソースタイプを正常に返し、成功しなければfalseを返します.Resourece socket_create(int protocol, int socketType, int commonProtocol); 今あなたはsocketを生み出して、それから?phpはsocketを操作する関数をいくつか提供します.あなたはsocketをIPにバインドして、socketの通信を傍受して、socketを受け入れることができます.関数がsocketを生成、受信、および傍受する方法を理解する例を見てみましょう.
上記の例は、自分のサーバ側を生成します.例1行目、$commonProtocol=getprotobyname(「tcp」)共通プロトコル名を使用して、プロトコルタイプを取得します.ここではTCP共通プロトコルを使用していますが、UDPまたはICMPプロトコルを使用したい場合は、getprotobyname()関数のパラメータを「udp」または「icmp」に変更する必要があります.getprotobyname()関数を使用せずにSOL_を指定する方法もあります.TCPまたはSOL_UDPはソケットにありますcreate()関数にあります.$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 例の2行目は、socketを生成し、socketリソースを返す例である.SOcketリソースのインスタンスがある場合は、IPアドレスとポートにsocketをバインドする必要があります.socket_bind($socket, ‘localhost’, 1337); ここでは、ローカルコンピュータ(127.0.0.1)にsocketをバインドし、1337ポートにsocketをバインドします.その後、入ってきたすべてのsocket接続を監視する必要があります.socket_listen($socket);4行目以降は、すべてのsocket関数と彼らの使用を理解する必要があります.表4:Socket関数関数名説明socket_accept()Socket接続を受け入れるsocket_bind()socketをIPアドレスとポートにバインドsocket_clear_Error()socketのエラーまたは最後のエラーコードsocket_をクリアclose()socketリソースを閉じるsocket_接続()socket接続を開始socket_create_Listen()指定したポートでsocketリスニングsocketを開きます.create_pair()は、区別のないペアのsocketを1つの配列に生成します.socket_create()はsocketを生成し、socketを生成するデータ構造socket_に相当する.get_option()socketオプションを取得socket_getpeername()リモート類似ホストのipアドレスsocket_を取得getsockname()ローカルsocketのipアドレスsocket_を取得iovec_add()分散/集約配列socket_に新しいベクトルを追加iovec_alloc()この関数は、読み書きを受信できるiovecデータ構造socket_を作成します.iovec_delete()割り当てられたiovec socketを削除iovec_fetch()は、指定されたiovecリソースのデータsocket_を返します.iovec_free()iovecリソースを解放socket_iovec_set()iovecのデータの新しい値socket_を設定するlast_Error()現在のsocketの最後のエラーコードsocket_を取得Listen()は、指定したsocketによるすべての接続をリスニングするsocket_read()指定長のデータを読み込むsocket_readv()分散/集約配列からのデータを読み出すsocket_recv()socketからキャッシュsocketにデータを終了recvfrom()は、指定されたsocketからデータを受け取り、指定されていない場合は現在のsocket socket_をデフォルト化します.recvmsg()iovecからメッセージを受信socket_select()多重選択socket_send()この関数は接続されたsocket socket_にデータを送信します.sendmsg()はsocket socket_にメッセージを送信するsendto()指定したアドレスのsocket socket_にメッセージを送信set_block()socketでブロックモードsocket_に設定set_nonblock()socketで非ブロックモードsocketに設定set_option()socketオプションsocket_を設定するshutdown()この関数を使用すると、読み取り、書き込み、または指定したsocket socket_を閉じることができます.strerror()は、指定したエラー番号の詳細なエラーsocket_を返します.write()socketキャッシュsocket_へのデータの書き込みwritev()分散/集約配列以上のすべての関数がPHPに書き込まれています.これらの関数を使用すると、socketを開く必要があります.開いていない場合はphpを編集してください.iniファイル、次の行の前のコメントを削除します:extension=php_sockets.dllコメントを削除できない場合は、次のコードを使用して拡張ライブラリをロードします.
socketが開いているかどうか分からない場合は、phpinfo()関数を使用してsocketが開いているかどうかを決定できます.phpinfo情報を見てsocketが開いているかどうかを知ることができます.phpinfo()socketに関する情報を表示◆サーバを生成するには、最初の例を改善します.指定したsocketを傍受し、ユーザーの接続を処理する必要があります.
この例を実行するには、コマンドプロンプトを使用します.理由は、Webページではなくサーバが生成されるからです.Webブラウザを使用してこのスクリプトを実行しようとすると、30秒の制限時間を超える可能性があります.次のコードを使用して無限の実行時間を設定できますが、コマンドプロンプトを使用して実行することをお勧めします.set_time_limit(0); あなたのコマンドプロンプトでこのスクリプトを簡単にテストします:Php.exe example01_server.phpシステムの環境変数にphp解釈器のパスを設定していない場合は、phpを与える必要があります.exeは詳細なパスを指定します.このサーバ側を実行すると、リモートログイン(telnet)でポート1337に接続してこのサーバをテストすることができます.
上のサーバ側には3つの問題があります.1.複数の接続を受け入れることはできません.2.一意のコマンドのみが完了します.3.Webブラウザでこのサーバーに接続できません.この最初の問題は解決しやすく、アプリケーションを使用して毎回サーバに接続することができます.しかし、次の問題は、Webページを使用してこのサーバに接続する必要があることです.これは難しいです.サーバーに接続を受け入れさせ、クライアントにデータを送り、接続を閉じて次の接続を待つことができます.前のコードに基づいてさらに改善し、次のコードを生成して新しいサーバー側を作成します.
このサーバー側は何をしますか?socketを初期化し、キャッシュ送受信データを開きます.接続を待機しています.接続が生成されると、サーバ側の画面に「Socket connected」が印刷されます.このサーバはバッファをチェックし、バッファにデータがあれば接続されたコンピュータにデータを送信します.そして、このデータの受信情報を送信し、情報を受信すると、データに情報を保存し、接続したコンピュータにこれらの情報を知らせ、最後に接続を閉じます.接続が閉じると、サーバは次の接続の処理を開始します.◆1つのクライアントが2つ目の問題を処理するのは容易である.phpページを生成してsocketに接続し、キャッシュにデータを送信して処理する必要があります.その後、処理後のデータが返され、サーバにデータを送信することができます.別のクライアント接続では、それらのデータが処理されます.次の例では、socketの使用例を示します.
この例のコードは、クライアントがサーバに接続されていることを示しています.クライアントがデータを読み込みます.このループに最初に到達した最初の接続であれば、このサーバは「NO DATA」を送信してクライアントに返す.状況が発生した場合、このクライアントは接続上にあります.クライアントはそのデータをサーバに送信し、データをサーバに送信し、クライアントは応答を待つ.応答が受信されると、応答は画面に書き込まれます.
<?php
$commonProtocol = getprotobyname(“tcp”);//
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);// socket socket
socket_bind($socket, ‘localhost’, 1337);// socket
socket_listen($socket);// socket
// More socket functionality to come
?>
上記の例は、自分のサーバ側を生成します.例1行目、$commonProtocol=getprotobyname(「tcp」)共通プロトコル名を使用して、プロトコルタイプを取得します.ここではTCP共通プロトコルを使用していますが、UDPまたはICMPプロトコルを使用したい場合は、getprotobyname()関数のパラメータを「udp」または「icmp」に変更する必要があります.getprotobyname()関数を使用せずにSOL_を指定する方法もあります.TCPまたはSOL_UDPはソケットにありますcreate()関数にあります.$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 例の2行目は、socketを生成し、socketリソースを返す例である.SOcketリソースのインスタンスがある場合は、IPアドレスとポートにsocketをバインドする必要があります.socket_bind($socket, ‘localhost’, 1337); ここでは、ローカルコンピュータ(127.0.0.1)にsocketをバインドし、1337ポートにsocketをバインドします.その後、入ってきたすべてのsocket接続を監視する必要があります.socket_listen($socket);4行目以降は、すべてのsocket関数と彼らの使用を理解する必要があります.表4:Socket関数関数名説明socket_accept()Socket接続を受け入れるsocket_bind()socketをIPアドレスとポートにバインドsocket_clear_Error()socketのエラーまたは最後のエラーコードsocket_をクリアclose()socketリソースを閉じるsocket_接続()socket接続を開始socket_create_Listen()指定したポートでsocketリスニングsocketを開きます.create_pair()は、区別のないペアのsocketを1つの配列に生成します.socket_create()はsocketを生成し、socketを生成するデータ構造socket_に相当する.get_option()socketオプションを取得socket_getpeername()リモート類似ホストのipアドレスsocket_を取得getsockname()ローカルsocketのipアドレスsocket_を取得iovec_add()分散/集約配列socket_に新しいベクトルを追加iovec_alloc()この関数は、読み書きを受信できるiovecデータ構造socket_を作成します.iovec_delete()割り当てられたiovec socketを削除iovec_fetch()は、指定されたiovecリソースのデータsocket_を返します.iovec_free()iovecリソースを解放socket_iovec_set()iovecのデータの新しい値socket_を設定するlast_Error()現在のsocketの最後のエラーコードsocket_を取得Listen()は、指定したsocketによるすべての接続をリスニングするsocket_read()指定長のデータを読み込むsocket_readv()分散/集約配列からのデータを読み出すsocket_recv()socketからキャッシュsocketにデータを終了recvfrom()は、指定されたsocketからデータを受け取り、指定されていない場合は現在のsocket socket_をデフォルト化します.recvmsg()iovecからメッセージを受信socket_select()多重選択socket_send()この関数は接続されたsocket socket_にデータを送信します.sendmsg()はsocket socket_にメッセージを送信するsendto()指定したアドレスのsocket socket_にメッセージを送信set_block()socketでブロックモードsocket_に設定set_nonblock()socketで非ブロックモードsocketに設定set_option()socketオプションsocket_を設定するshutdown()この関数を使用すると、読み取り、書き込み、または指定したsocket socket_を閉じることができます.strerror()は、指定したエラー番号の詳細なエラーsocket_を返します.write()socketキャッシュsocket_へのデータの書き込みwritev()分散/集約配列以上のすべての関数がPHPに書き込まれています.これらの関数を使用すると、socketを開く必要があります.開いていない場合はphpを編集してください.iniファイル、次の行の前のコメントを削除します:extension=php_sockets.dllコメントを削除できない場合は、次のコードを使用して拡張ライブラリをロードします.
<?php
if(!extension_loaded(‘sockets’)) {
if(strtoupper(substr(PHP_OS, 3)) == “WIN”) {
dl(‘php_sockets.dll’);
}else{
dl(‘sockets.so’);
}
}
?>
socketが開いているかどうか分からない場合は、phpinfo()関数を使用してsocketが開いているかどうかを決定できます.phpinfo情報を見てsocketが開いているかどうかを知ることができます.phpinfo()socketに関する情報を表示◆サーバを生成するには、最初の例を改善します.指定したsocketを傍受し、ユーザーの接続を処理する必要があります.
<?php
$commonProtocol = getprotobyname("tcp");
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, 'localhost', 1337);
socket_listen($socket);
// Accept any incoming connections to the server
$connection = socket_accept($socket);
if($connection){
socket_write($connection, "You have connected to the socket...
\r");
}
?>
この例を実行するには、コマンドプロンプトを使用します.理由は、Webページではなくサーバが生成されるからです.Webブラウザを使用してこのスクリプトを実行しようとすると、30秒の制限時間を超える可能性があります.次のコードを使用して無限の実行時間を設定できますが、コマンドプロンプトを使用して実行することをお勧めします.set_time_limit(0); あなたのコマンドプロンプトでこのスクリプトを簡単にテストします:Php.exe example01_server.phpシステムの環境変数にphp解釈器のパスを設定していない場合は、phpを与える必要があります.exeは詳細なパスを指定します.このサーバ側を実行すると、リモートログイン(telnet)でポート1337に接続してこのサーバをテストすることができます.
上のサーバ側には3つの問題があります.1.複数の接続を受け入れることはできません.2.一意のコマンドのみが完了します.3.Webブラウザでこのサーバーに接続できません.この最初の問題は解決しやすく、アプリケーションを使用して毎回サーバに接続することができます.しかし、次の問題は、Webページを使用してこのサーバに接続する必要があることです.これは難しいです.サーバーに接続を受け入れさせ、クライアントにデータを送り、接続を閉じて次の接続を待つことができます.前のコードに基づいてさらに改善し、次のコードを生成して新しいサーバー側を作成します.
<?php
// Set up our socket
$commonProtocol = getprotobyname("tcp");
$socket = socket_create(AF_INET, SOCK_STREAM, $commonProtocol);
socket_bind($socket, 'localhost', 1337); //socket_bind() socket IP
socket_listen($socket);
// Initialize the buffer
$buffer = "NO DATA";
while(true) {
// Accept any connections coming in on this socket
$connection = socket_accept($socket);//socket_accept() Socket
printf("Socket connected\r
");
// Check to see if there is anything in the buffer
if($buffer != ""){
printf("Something is in the buffer...sending data...\r
");
socket_write($connection, $buffer . "\r
"); //socket_write() socket
printf("Wrote to socket\r
");
}else {
printf("No Data in the buffer\r
");
}
// Get the input
while($data = socket_read($connection, 1024, PHP_NORMAL_READ))//socket_read()
{
$buffer = $data;
socket_write($connection, "Information Received\r
");
printf("Buffer: " . $buffer . "\r
");
}
socket_close($connection); //socket_close() socket
printf("Closed the socket\r
\r
");
}
?>
このサーバー側は何をしますか?socketを初期化し、キャッシュ送受信データを開きます.接続を待機しています.接続が生成されると、サーバ側の画面に「Socket connected」が印刷されます.このサーバはバッファをチェックし、バッファにデータがあれば接続されたコンピュータにデータを送信します.そして、このデータの受信情報を送信し、情報を受信すると、データに情報を保存し、接続したコンピュータにこれらの情報を知らせ、最後に接続を閉じます.接続が閉じると、サーバは次の接続の処理を開始します.◆1つのクライアントが2つ目の問題を処理するのは容易である.phpページを生成してsocketに接続し、キャッシュにデータを送信して処理する必要があります.その後、処理後のデータが返され、サーバにデータを送信することができます.別のクライアント接続では、それらのデータが処理されます.次の例では、socketの使用例を示します.
<?php
// Create the socket and connect
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$connection = socket_connect($socket,’localhost’, 1337);
while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ)) {
if($buffer == “NO DATA”) {
echo(“<p>NO DATA</p>”);
break;
}else{
// Do something with the data in the buffer
echo(“<p>Buffer Data: “ . $buffer . “</p>”);
}
}
echo(“<p>Writing to Socket</p>”);
// Write some test data to our socket
if(!socket_write($socket, “SOME DATA\r
”)){
echo(“<p>Write failed</p>”);
}
// Read any response from the socket
while($buffer = socket_read($socket, 1024, PHP_NORMAL_READ)){
echo(“<p>Data sent was: SOME DATA<br> Response was:” . $buffer . “</p>”);
}
echo(“<p>Done Reading from Socket</p>”);
?>
この例のコードは、クライアントがサーバに接続されていることを示しています.クライアントがデータを読み込みます.このループに最初に到達した最初の接続であれば、このサーバは「NO DATA」を送信してクライアントに返す.状況が発生した場合、このクライアントは接続上にあります.クライアントはそのデータをサーバに送信し、データをサーバに送信し、クライアントは応答を待つ.応答が受信されると、応答は画面に書き込まれます.