深入浅出php socketプログラミング


TCP/IP、UDP、Socketプログラミングという言葉はよく知らないですよね?ネット技術の発展に伴って、これらの言葉は耳にあふれています。すみません、
1.TCP/IP、UDPとは?
2.ソケットはどこにありますか?
3.ソケットは何ですか?
4.それらは使えますか?
TCP/IP、UDPとは?
TCP/IP(Transyssion Control Protocol/Internet Protocol)は、転送制御プロトコル/インターネット間プロトコルであり、工業規格のプロトコルセットであり、広域ネットワーク(WANs)のために設計されている。
UDP(User Data Protocol)は、TCPに対応するプロトコルです。これはTCP/IPプロトコルの一つです。
これらのプロトコルの関係を示す図がここにあります。

TCP/IPプロトコル族は、輸送層、ネットワーク層、リンク層を含む。TCP/IPとUDPの関係はもう分かりましたよね。
ソケットはどこにありますか?
図1では、私たちはソケットの影を見ていませんでしたが、どこにありますか?やはり図で話します。一目瞭然です。

ソケットはここにありますか?
ソケットは何ですか?
ソケットはアプリケーション層とTCP/IPプロトコル族が通信する中間ソフトウェア抽象層であり、インタフェースのセットである。デザインモードでは、ソケットは実際には外観モードです。複雑なTCP/IPプロトコル族をソケットインターフェースの後ろに隠しています。ユーザーにとって、簡単なインターフェースのセットは全部です。指定されたプロトコルに合うように、Socketにデータを組織させます。
それらは使えますか?
昔の人がたくさんのことをしてくれました。インターネット間の通信も簡単になりました。でも、やはりたくさんの仕事があります。以前、ソケットのプログラミングを聞いたことがありますが、かなり深いプログラミング知識だと思いましたが、ソケットのプログラミングの原理がわかれば、神秘的なベールが解けます。
一つの生活の中のシーン。友達に電話して、先に電話してください。友達が電話のベルの音を聞いてから電話を切ります。この時あなたとあなたの友達は接続を作って、話ができます。などの交流が終わり、電話を切って話を終わります。生活の中のシーンはこの仕事の原理を説明して、TCP/IPプロトコル族は生活の中で誕生するのかも知れなくて、これも一定ではありません。

まずサーバから話します。サーバー側はまずソケットを初期化して、ポートと紐付けして、ポートをモニターして、acceptブロックを呼び出して、クライアントの接続を待つ。このとき、クライアントが一つのソケットを初期化してサーバに接続すると、接続が成功すると、クライアントとサーバ端との接続が確立されます。クライアントはデータ要求を送信し、サーバ端は要求を受信して要求を処理し、その後、応答データをクライアントに送信し、クライアントはデータを読み取り、最後に接続をオフにして、一回のインタラクションが終了します。
socket関連関数:
------------------------------------------------
socketaccept()はソケット接続を受け付けます。
socketビッド()socketをIPアドレスとポートに結びつける。
socketclear_error()socketのエラーまたは最後のエラーコードをクリアします。
socketclose()socketリソースをクローズします。
socketconnect()一つのsocket接続を開始します。
socketクリアードlisten()指定されたポートでsocketを開いて傍受します。
socketクリアードpair()はペアの区別のないsocketを一つの配列に生成します。
socketcreate()はsocketを生成します。socketを生成するデータ構造に相当します。
socketゲットするoption()取得socketオプション
socketgetpeername()は、遠隔類似ホストのipアドレスを取得する。
socketget sockname()はローカルsocketのipアドレスを取得します。
socket公文書add()新しいベクトルを一つの分散/集合の行列に追加します。
socket公文書alloc()という関数は読み書きを受信できるiovecデータ構造を作成します。
socket公文書delete()割り当てられたiovecを削除します。
socket公文書fetch()は指定されたiovecリソースのデータを返します。
socket公文書free()Ovecリソースをリリースします。
socket公文書set()iovecのデータの新しい値を設定します。
socketラスター.error()は現在のsocketの最後のエラーコードを取得します。
socketlisten()傍受は指定されたsocketのすべての接続によって行われます。
socketread()指定長さのデータを読みだします。
socketreadv()は、分散/集約配列からのデータを読み出す。
socketrecv()socketからデータをキャッシュに終了します。
socketrecvfrom()指定されたsocketからデータを受け取り、指定されていない場合は現在のsocketをデフォルトにします。
socketrecvmsg()はiovecからメッセージを受け取る。
socket複数選択
socketsend()この関数は接続されたsocketにデータを送信します。
socketsendmsg()メッセージをsocketに送ります。
socketsendto()指定された住所のsocketにメッセージを送ります。
socketsetブロックモードに設定します。
socketsetnonblock()socketはブロックモードではない設定になります。
socketsetoption()設定socketオプション
socketshutdown()この関数により、読み、書き、または指定されたsocketを閉じることができます。
socketsterror()は指定されたエラー番号の詳細なエラーを返します。
socketwrite()データをsocketキャッシュに書き込みます。
socketwritev()データを分散/集約配列に書き込みます。
実例一:socket通信デモ
サーバ端:

<?php
//             
set_time_limit(0);

$ip = '127.0.0.1';
$port = 1935;

/*
 +-------------------------------
 *  @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()       :".socket_strerror($sock)."
"; } if(($ret = socket_bind($sock,$ip,$port)) < 0) { echo "socket_bind() :".socket_strerror($ret)."
"; } if(($ret = socket_listen($sock,4)) < 0) { echo "socket_listen() :".socket_strerror($ret)."
"; } $count = 0; do { if (($msgsock = socket_accept($sock)) < 0) { echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "
"; break; } else { // $msg =" !
"; socket_write($msgsock, $msg, strlen($msg)); echo "
"; $buf = socket_read($msgsock,8192); $talkback = " :$buf
"; echo $talkback; if(++$count >= 5){ break; }; } //echo $buf; socket_close($msgsock); } while (true); socket_close($sock); ?>
これはsocketのサービスコードです。cmdを実行して、自分のプログラムの保存経路に注意してください。

反映されていません。現在のサービス端末のプログラムはすでに実行されています。ポートはすでにモニターを開始しました。netstat-anoを実行するとポートの状況が確認できます。私のは1935ポートです。

ほら、ポートはもうLISTING状態です。次にクライアントプログラムを実行すれば接続できます。コードを付ける

<?php
error_reporting(E_ALL);
set_time_limit(0);
echo "<h2>TCP/IP Connection</h2>
"; $port = 1935; $ip = "127.0.0.1"; /* +------------------------------- * @socket +------------------------------- * @socket_create * @socket_connect * @socket_write * @socket_read * @socket_close +-------------------------------- */ $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket < 0) { echo "socket_create() failed: reason: " . socket_strerror($socket) . "
"; }else { echo "OK.
"; } echo " '$ip' '$port'...
"; $result = socket_connect($socket, $ip, $port); if ($result < 0) { echo "socket_connect() failed.
Reason: ($result) " . socket_strerror($result) . "
"; }else { echo " OK
"; } $in = "Ho\r
"; $in .= "first blood\r
"; $out = ''; if(!socket_write($socket, $in, strlen($in))) { echo "socket_write() failed: reason: " . socket_strerror($socket) . "
"; }else { echo " !
"; echo " :<font color='red'>$in</font> <br>"; } while($out = socket_read($socket, 8192)) { echo " !
"; echo " :",$out; } echo " SOCKET...
"; socket_close($socket); echo " OK
"; ?>

このクライアントはすでにサービスに接続されています。
実例二:コードの詳細

//          
$host = "192.168.1.99";
$port = 1234;
//       
set_time_limit(0);
//     Socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not createsocket
"); // Socket $result = socket_bind($socket, $host, $port) or die("Could not bind tosocket
"); // $result = socket_listen($socket, 3) or die("Could not set up socketlistener
"); // accept incoming connections // Socket $spawn = socket_accept($socket) or die("Could not accept incomingconnection
"); // $input = socket_read($spawn, 1024) or die("Could not read input
"); // $input = trim($input); // $output = strrev($input) . "
"; socket_write($spawn, $output, strlen ($output)) or die("Could not write output
"); // sockets socket_close($spawn); socket_close($socket);
以下はその各ステップの詳細な説明である。
1.第1ステップは、2つの変数を作成して、ソケットが実行するサーバのIPアドレスとポートを保存します。あなた自身のサーバとポート(このポートは1から65535までの数字でもいいです。)に設定してもいいです。このポートは使用されていないことが前提です。

//
$host = "192.168.1.99";
$port = 1234;
2.サーバ側でset_を使用することができます。time_Out()関数は、PHPがクライアントの接続を待っている間にタイムアウトしないことを確認します。

//
set_time_limit(0);
3.前の上に、今はsocketを使うべきです。creat関数はSocketを作成しました。この関数はソケットのハンドルを返します。このハンドルは後のすべての関数に使われます。

// Socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create
socket
");
第一パラメータ「AF_」INETはドメイン名を指定するために使用されます。
二つ目のパラメータ「SOCK_」STREMはどのタイプのSocketを作成するかを関数に教えます。(この例ではTCPタイプです。)
したがって、UDP Socketを作成したいなら、次のコードが使えます。

// socket
$socket = socket_create(AF_INET, SOCK_DGRAM, 0) or die("Could not create
socket
");
4.一旦ソケットのハンドルを作成したら、次は指定された住所とポートに指定またはバインドされます。これはsocket_を通じてできます。bind()関数は完成に来ます。

// socket to
$result = socket_bind($socket, $host, $port) or die("Could not bind to
socket
");
5.Socketが作成されて一つのポートに結び付けられたら、外部の接続をモニターすることができます。PHPはsocket_から許可します。listen()関数でモニターを開始します。同時に数字を指定できます。(この例では2番目のパラメータです。3)

//
$result = socket_listen($socket, 3) or die("Could not set up socket
listener
");
6.今まであなたのサーバはクライアントからの接続要求を待つ以外はほとんど何もしていません。クライアントからの接続が受信されると、socket_accept()関数は、接続要求を受信し、他のサブソケットを呼び出してクライアントCサーバ間の情報を処理する役割を果たします。

//
// socket
$spawn = socket_accept($socket) or die("Could not accept incoming
connection
");
この子socketは今すぐ後のクライアントCサーバ通信に使われます。
7.接続が確立されると、サーバーはクライアントからの入力情報の送信を待っています。この書き込みはsocket_でいいです。read()関数を取得し、PHPのinput変数に値を与えます。

//
$input = socket_read($spawn, 1024) or die("Could not read input
");
?&gt;
socker_読み込んだバイト数を指定するために、readのパラメータを使用して、クライアントからデータを取得するサイズを制限することができます。
注意:socket_read関数はシェルエンドのデータを読み続けます。出会うまでは\tまたは\0文字です。PHPスクリプトはこの文字を入力の終端符と見なします。
8.サーバはこれらを処理しなければなりません。クライアントから送られたデータです。(この例ではデータの入力とクライアントへの返信だけを処理します。)この部分は、socket_でいいです。write()関数は、通信socketによって一つのデータがクライアントに送信されることを可能にするために完成される。

//
$output = strrev($input) . "
";
socket_write($spawn, $output, strlen ($output)) or die("Could not write
output
");
9.出力がクライアントに戻されると、親/子socketは全部socket_を通過するべきです。関数を終了します。

// sockets
socket_close($spawn);
socket_close($socket);