ホームページ  >  記事  >  バックエンド開発  >  PHPソケットとは何ですか?

PHPソケットとは何ですか?

怪我咯
怪我咯オリジナル
2017-07-05 09:37:571392ブラウズ

この記事では、主に PHP ソケット プログラミングを簡単に紹介します。この記事では、ソケットの関連知識と PHP ソケット プログラミングのサンプルのパッケージ内容を詳しく説明します。 、UDP、およびソケットプログラミングは奇妙ではないでしょうか。ネットワーク技術の発展に伴い、このような言葉が私たちの耳に溢れています。そこでお聞きしたいのは:

1. TCP/IP と UDP とは何ですか?

2. ソケットはどこですか?

3.ソケットとは何ですか?
4. 使えますか?

TCP/IP と UDP とは何ですか?

TCP/IP (伝送制御プロトコル/インターネット プロトコル) は、ワイド エリア ネットワーク (WAN) 用に設計された業界標準プロトコル セットです。

UDP(User Data Protocol)は、TCPに相当するプロトコルです。これは、TCP/IP プロトコル スイートのメンバーです。

これらのプロトコル間の関係を示す図は次のとおりです。

TCP/IP プロトコル スイートには、トランスポート層、ネットワーク層、リンク層が含まれます。これで、TCP/IP と UDP の関係がわかりました。

ソケットはどこですか?

図 1 では、Socket の影が見えませんが、それはどこにあるのでしょうか?写真そのものに語ってもらいましょう。

ソケットがここにあることが判明しました。

ソケットとは何ですか?

ソケットは、アプリケーション層とTCP/IPプロトコルスイート間の通信のための中間ソフトウェア抽象化層です。インターフェースのセットです。

デザイン パターン

では、Socket は実際にはファサード パターンであり、複雑な TCP/IP プロトコル ファミリを Socket インターフェイスの背後に隠します。ユーザーにとっては、一連の単純なインターフェイスだけで、Socket は指定されたプロトコルに準拠するようにデータを編成できます。

使えますか?

先人たちは私たちのために多くのことをしてくれ、ネットワーク間の通信ははるかに簡単になりましたが、結局のところ、やるべきことはまだたくさんあります。以前ソケットプログラミングについて聞いたとき、比較的高度なプログラミング知識だと思っていましたが、ソケットプログラミングの動作原理を理解すれば、その謎は解けます。

人生の一場面。友人に電話したい場合は、最初にその番号をダイヤルします。呼び出し音が聞こえたら、友人は電話に出ます。この時点で、あなたと友人は接続され、通話することができます。通話が終了したら電話を切って会話を終了します。 TCP/IP プロトコル ファミリは人生の中で誕生したのかもしれませんが、必ずしもそうではありません。


サーバー側から始めましょう。サーバーはまずソケットを初期化し、次にポートにバインドし、ポートをリッスンし、accept を呼び出してブロックし、クライアントが接続するのを待ちます。このとき、クライアントがSocketを初期化してからサーバーに接続すると、接続に成功するとクライアントとサーバー間の接続が確立されます。クライアントがデータ要求を送信し、サーバーが要求を受信して​​処理し、次に応答データをクライアントに送信し、クライアントがデータを読み取り、最後に接続を閉じて対話が終了します。

ソケット関連関数:
------------------------------------------ --- --------------------------------------------------- --- --
socket_accept() ソケット接続を受け入れる
socket_bind() ソケットを IP アドレスとポートにバインドする
socket_clear_error() ソケット エラーまたは最後のエラー コードをクリアする
socket_close() ソケット リソースを閉じる
socket_connect()ソケット接続を開始します
socket_create_listen() 指定されたポートでリッスンするソケットを開きます
socket_create_pair() 未区別のソケットのペアを配列に生成します
socket_create() ソケットを生成します。これはソケットデータ構造を生成するのと同等です
socket_get_option()ソケット オプションを取得します
socket_getpeername() リモートの同様のホストの IP アドレスを取得します
socket_getsockname() ローカル ソケットの IP アドレスを取得します
socket_iovec_add() 新しいベクトルを分散/集合配列に追加します
socket_iovec_alloc() この関数は、 sender 読み取りおよび書き込み iovec データ構造を受信
socket_iovec_delete() 割り当てられた iovec を削除
socket_iovec_fetch() 指定された iovec リソースのデータを返す
socket_iovec_free() iovec リソースを解放する
socket_iovec_set() iovec データの新しい値を設定する
socket_last_error ( ) 現在のソケットの最後のエラーコードを取得します
socket_listen() 指定されたソケットからのすべての接続をリッスンします
socket_read() 指定された長さのデータを読み取ります
socket_readv() 分散/集約配列からデータを読み取ります
socket_recv()ソケットから終了キャッシュへのデータ
socket_recvfrom()は指定されたソケットからデータを受け取ります、指定されていない場合は現在のソケットがデフォルトになります
socket_recvmsg()はiovecからメッセージを受け取ります
socket_select()複数選択
socket_send()この関数はデータをに送信します接続されたソケット
socket_sendmsg() ソケットにメッセージを送信socket_sendto() 指定したアドレスのソケットにメッセージを送信
socket_set_block() ソケットをブロックモードに設定
socket_set_nonblock() ソケットを非ブロックに設定mode
socket_set_option() ソケットオプションを設定します
socket_shutdown() この関数を使用すると、読み取り、書き込み、または指定されたソケットを閉じることができます
socket_strerror() は、指定されたエラー番号を持つ詳細なエラーを返します
socket_write() ソケットキャッシュにデータを書き込みます
socket_writev() は分散/集約配列にデータを書き込みます

ケース 1: ソケット通信のデモ

サーバー側:

<?php
//确保在连接客户端时不会超时
set_time_limit(0);

$ip = &#39;127.0.0.1&#39;;
$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)."\n";
}

if(($ret = socket_bind($sock,$ip,$port)) < 0) {
  echo "socket_bind() 失败的原因是:".socket_strerror($ret)."\n";
}

if(($ret = socket_listen($sock,4)) < 0) {
  echo "socket_listen() 失败的原因是:".socket_strerror($ret)."\n";
}

$count = 0;

do {
  if (($msgsock = socket_accept($sock)) < 0) {
    echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
    break;
  } else {
    
    //发到客户端
    $msg ="测试成功!\n";
    socket_write($msgsock, $msg, strlen($msg));
    
    echo "测试成功了啊\n";
    $buf = socket_read($msgsock,8192);
    
    
    $talkback = "收到的信息:$buf\n";
    echo $talkback;
    
    if(++$count >= 5){
      break;
    };
    
  
  }
  //echo $buf;
  socket_close($msgsock);

} while (true);

socket_close($sock);
?>

これはソケットのサーバー側のコードです。次に cmd を実行し、独自のプログラムのストレージ パスに注意してください。

反映はありません。サーバー プログラムが実行を開始し、ポートがリッスンを開始しました。 netstat -ano を実行してポートのステータスを確認します。私のポートは 1935

です。ポートはすでに LISTENING 状態になっています。次に、クライアント プログラムを実行して接続するだけです。コードをアップロードします

<?php
error_reporting(E_ALL);
set_time_limit(0);
echo "<h2>TCP/IP Connection</h2>\n";

$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) . "\n";
}else {
  echo "OK.\n";
}

echo "试图连接 &#39;$ip&#39; 端口 &#39;$port&#39;...\n";
$result = socket_connect($socket, $ip, $port);
if ($result < 0) {
  echo "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
}else {
  echo "连接OK\n";
}

$in = "Ho\r\n";
$in .= "first blood\r\n";
$out = &#39;&#39;;

if(!socket_write($socket, $in, strlen($in))) {
  echo "socket_write() failed: reason: " . socket_strerror($socket) . "\n";
}else {
  echo "发送到服务器信息成功!\n";
  echo "发送的内容为:<font color=&#39;red&#39;>$in</font> <br>";
}

while($out = socket_read($socket, 8192)) {
  echo "接收服务器回传信息成功!\n";
  echo "接受的内容为:",$out;
}


echo "关闭SOCKET...\n";
socket_close($socket);
echo "关闭OK\n";
?>

これで、クライアントがサーバーに接続されました。

ケース 2: コードの詳細説明

// 设置一些基本的变量
$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\n");
//绑定Socket到端口
$result = socket_bind($socket, $host, $port) or die("Could not bind tosocket\n");
// 开始监听链接
$result = socket_listen($socket, 3) or die("Could not set up socketlistener\n");
// accept incoming connections
// 另一个Socket来处理通信
$spawn = socket_accept($socket) or die("Could not accept incomingconnection\n");
// 获得客户端的输入
$input = socket_read($spawn, 1024) or die("Could not read input\n");
// 清空输入字符串
$input = trim($input);
//处理客户端输入并返回结果
$output = strrev($input) . "\n";
socket_write($spawn, $output, strlen ($output)) or die("Could not write
output\n");
// 关闭sockets
socket_close($spawn);
socket_close($socket);

以下は各ステップの詳細な説明です:

1. 最初のステップは、ソケットが実行されているサーバーの IP アドレスとポートを保存するための 2 つの変数を作成することです。このポートが使用されていない場合は、独自のサーバーとポート (このポートは 1 ~ 65535 の数字にすることができます) に設定できます。 コードは次のとおりです:

// 设置两个变量
$host = "192.168.1.99";
$port = 1234;

2。 PHP が実行されていることを確認するためのサーバー側の set_time_out() 関数。 クライアントの接続を待機するときにタイムアウトは発生しません。

コードは次のとおりです。

// 超时时间
set_time_limit(0);

3.今度は、socket_creat() 関数を使用してソケットを作成します。この関数は、今後のすべての関数で使用されるソケット ハンドルを返します。 コードは次のとおりです。

// 创建Socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create
socket\n");
最初のパラメーター「AF_INET」は、指定するために使用されます。ドメイン名;
2 番目のパラメータ「SOCK_STREM」は、作成されるソケットのタイプを関数に指示します (この例では、 は TCP タイプです)

したがって、UDP ソケットを作成したい場合は、次のコードを使用できます。 :

コードは次のとおりです:

// 创建 socket
$socket = socket_create(AF_INET, SOCK_DGRAM, 0) or die("Could not create
socket\n");

4. ソケット ハンドルが作成されたら、次のステップは、ソケット ハンドルを指定するか、指定したアドレスとポートにバインドすることです。これは、socket_bind() 関数を通じて実行できます。コードは次のとおりです:

// 绑定 socket to 指定地址和端口
$result = socket_bind($socket, $host, $port) or die("Could not bind to
socket\n");

5. ソケットが作成され、ポートにバインドされると、PHP では、socket_listen() 関数を通じてリスニング関数を開始できます。数値 (この例では、2 番目のパラメーター: 3)

コードは次のとおりです:

// 开始监听连接
$result = socket_listen($socket, 3) or die("Could not set up socket
listener\n");

6. これまで、サーバーはからのメッセージを待つことしかできません。基本的には、クライアントの接続要求以外は何も行われません。クライアント接続が受信されると、socket_accept() 関数が動作し、接続リクエストを受信し、クライアントとサーバーの情報を処理します。

 代码如下:

//接受请求链接
// 调用子socket 处理信息
$spawn = socket_accept($socket) or die("Could not accept incoming
connection\n");

这个子socket现在就可以被随后的客户端–服务器通信所用了.

7.当一个连接被建立后,服务器就会等待客户端发送一些输入信息,这写信息可以由socket_read()函数来获得,并把它赋值给PHP的$input变量.

 代码如下:

// 读取客户端输入
$input = socket_read($spawn, 1024) or die("Could not read input\n");
?>

socker_read的第而个参数用以指定读入的字节数,你可以通过它来限制从客户端获取数据的大小.

注意:socket_read函数会一直读取壳户端数据,直到遇见\n,\t或者\0字符.PHP脚本把这写字符看做是输入的结束符.

8.现在服务器必须处理这些由客户端发来是数据(在这个例子中的处理仅仅包含数据的输入和回传到客户端).这部分可以由socket_write()函数来完成(使得由通信socket发回一个数据流到客户端成为可能)

代码如下:

// 处理客户端输入并返回数据
$output = strrev($input) . "\n";
socket_write($spawn, $output, strlen ($output)) or die("Could not write
output\n");

9.一旦输出被返回到客户端,父/子socket都应通过socket_close()函数来终止

 代码如下:

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

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

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