ホームページ  >  記事  >  バックエンド開発  >  PHP のソケット通信原理の簡単な紹介

PHP のソケット通信原理の簡単な紹介

WBOY
WBOYオリジナル
2016-08-08 09:23:28909ブラウズ

TCP/IPUDPSocketプログラミングという言葉に馴染みがありませんよね?ネットワーク技術の発展に伴い、こんな言葉が私たちの耳に溢れています。そこでお聞きしたいのですが:
1. TCP/IPUDPとは何ですか?
2. ソケットはどこですか?
3. ソケットとは何ですか?
4. 使いますか?
TCP/IPUDPとは何ですか?

TCP/IP ( 伝送制御プロトコル/インターネット プロトコル ) 伝送制御プロトコル / インターネット プロトコルCol は、広域ネットワーク ( WAN ) 用に設計された業界標準プロトコル セットです。
UDPUser Data Protocol、User Datagram 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() この関数送受信可能なソケットを作成する 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() は、scatter/ からデータを読み取ります集合配列
socket_recv() ソケットからのデータを終了し、キャッシュへ
socket_recvfrom() 指定されたソケットからデータを受け取り、指定されていない場合、現在のソケットがデフォルトになります
socket_recvmsg() iovec からメッセージを受信します
socket_select() 複数選択
socket_send() この関数は、接続されているソケットにデータを送信します
socket_sendmsg() ソケットにメッセージを送信します
socket_sendto() 指定されたアドレスのソケットにメッセージを送信します
socket_set_block() ソケットをブロックモードに設定します
socket_set_nonblock() Setソケットをノンブロックモードにします
socket_set_option() ソケットオプションを設定します
socket_shutdown() この関数を使用すると、読み取り、書き込み、または指定されたソケットを閉じることができます
socket_strerror() は、指定されたエラー番号を持つ詳細なエラーを返します
socket_write()データをソケットキャッシュに書き込みます
socket_writev() データを分散/集約配列に書き込みます

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

サーバー側:

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

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

/*
 &#43;-------------------------------
 *    @socket通信整个过程
 &#43;-------------------------------
 *    @socket_create
 *    @socket_bind
 *    @socket_listen
 *    @socket_accept
 *    @socket_read
 *    @socket_write
 *    @socket_close
 &#43;--------------------------------
 */

/*----------------    以下操作都是手册上的    -------------------*/
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(&#43;&#43;$count >= 5){
            break;
        };
        
    
    }
    //echo $buf;
    socket_close($msgsock);

} while (true);

socket_close($sock);
?></span>

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

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

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

<span><?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 "试图连接 '$ip' 端口 '$port'...\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 = '';

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

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


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

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

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

// 基本的な変数を設定します
$host = "192.168.1.99"
;
$port = 1234
;
/ /タイムアウトを設定する
set_time_limit(0
);
// ソケットを作成する
$socket = socket_create (AF_INETSOCK_STREAM , 0) or die("Could not createocketn"
);
//ソケットをポートにバインドする
$result = _バインド( $ソケット, $host, $port) または die("Could not binding tosocketn");

// リンク
$ の結果の監視を開始します
= socket_listen($socket, 3) or die(「socketlistenernをセットアップできませんでした」);
// 受信接続を受け入れます //通信を処理する別のソケット
$spawn
=
socket_accept($socket) or die("受信接続を受け入れられませんでした"); / / 入力を取得するクライアントから
$input
= socket_read
($spawn, 1024) または die("入力を読み取れませんでした") ); //入力文字列をクリアします
$input
=trim
($input);//クライアント入力を処理し、結果を返します
$output
= strrev
($input) $outputstrlen (
$output)) or die(
) 「出力を書き込めませんでした」 );//ソケットを閉じるsocket_close( $spawn );
socket_close
(
) $socket
);
以下は各ステップの詳細な説明:例:ウェブサイトデザイン会社
デザイン会社
インターネットマーケティングインターネットプロモーション
インターネット最適化
ウェブサイトプロモーションウェブサイトの最適化ウェブサイトの運用などはすべて同様の手順で作成されます。 1. 最初のステップは、Socket が実行されているサーバーの IP アドレスとポートを保存する 2 つの変数を作成することです。これを独自の Web サイトのデザイン サーバーおよび Web サイトの構築 として設定できます。 ポート (このポートは 1 ~ 65535 の数字にすることができます)、このポートが使用されていない場合に限ります。 // 設定 2 つの変数 $host = "192.168.1.99"
;$port 1234;コード>

2.サーバー側では、set_time_out()関数

を使用して、クライアントの接続を待機している間にPHPがタイムアウトしないようにすることができます。
[クリップボードにコピー]

<span>// 设置两个变量<br></span><span>$host </span><span>= </span><span>"192.168.1.99"</span><span>;<br></span><span>$port </span><span>= </span><span>1234</span><span>;</span><br>

2.在服务器端可以使用set_time_out()函数来确保PHP在等待客户端连接时不会超时.建网站

[Copy to clipboard]

PHP CODE:

<span>// 超时时间<br></span><span>set_time_limit</span><span>(</span><span>0</span><span>);</span><br>PHP CODE:

// タイムアウト set_time_limit(0);

3.基本的な部分を説明します。今度は、socket_creat() 関数を使用してソケットを作成します。この関数は、Web サイトを作成するための今後のすべての関数で使用されるソケット ハンドルを返します。クリップボードにコピー]🎜🎜🎜
PHP コード:

<code><span>// 创建Socket<br></span><span>$socket </span><span>= </span><span>socket_create</span><span>(</span><span>AF_INET</span><span>, </span><span>SOCK_STREAM</span><span>, </span><span>0</span><span>) or die(</span><span>"Could not create<br>socketn"</span><span>);</span><br>

第一个参数”AF_INET”用来指定域名;
第二个参数”SOCK_STREM”告诉函数将创建一个什么型的Socket(在这个例子中是TCP型)
因此,如果你想创建一个UDP Socket的话,你可以使用如下的代码:

[Copy to clipboard]

PHP CODE:

<span>// 创建 socket<br></span><span>$socket </span><span>= </span><span>socket_create</span><span>(</span><span>AF_INET</span><span>, </span><span>SOCK_DGRAM</span><span>, </span><span>0</span><span>) or die(</span><span>"Could not create<br>socketn"</span><span>);</span><br>

4.一旦创建了一个Socket句柄,下一步就是指定或者绑定它到指定的网站建设公司地址和企业网站建设端口.这可以通过socket_bind()函数来完成.

[Copy to clipboard]

PHP CODE:

<span>// 绑定 socket to 指定地址和端口<br></span><span>$result </span><span>= </span><span>socket_bind</span><span>(</span><span>$socket</span><span>, </span><span>$host</span><span>, </span><span>$port</span><span>) or die(</span><span>"Could not bind to<br>socketn"</span><span>);</span><br>

5.当Socket被创建好并绑定到一个端口后,就可以开始监听外部的连接了.PHP允许你由socket_listen()函数来开始一个网站制作公司监听,同时你可以指定一个数字(在这个例子中就是第二个参数:3)

[Copy to clipboard]

PHP CODE:

<span>// 开始监听连接<br></span><span>$result </span><span>= </span><span>socket_listen</span><span>(</span><span>$socket</span><span>, </span><span>3</span><span>) or die(</span><span>"Could not set up socket<br>listenern"</span><span>);</span><br>

6.到现在,你的服务器除了等待来自客户端的连接请求外基本上什么也没有做.一旦一个客户端的连接被收到,socket_accept()函数便开始起作用了,它接收连接请求并调用另一个子Socket来处理客户端–网站制作服务器间的信息.

[Copy to clipboard]

PHP CODE:

<span>//接受请求链接<br>// 调用子socket 处理信息<br></span><span>$spawn </span><span>= </span><span>socket_accept</span><span>(</span><span>$socket</span><span>) or die(</span><span>"Could not accept incoming<br>connectionn"</span><span>);</span><br>

这个子socket现在就可以被随后的网页制作客户端–服务器通信所用了.
7.当一个连接被建立后,
网页设计服务器就会等待客户端发送一些输入信息,这写信息可以由socket_read()函数来获得,并把它赋值给PHP的$input变量.

[Copy to clipboard]

PHP CODE:

<span>// 读取客户端输入<br></span><span>$input </span><span>= </span><span>socket_read</span><span>(</span><span>$spawn</span><span>, </span><span>1024</span><span>) or die(</span><span>"Could not read inputn"</span><span>);<br>?&</span><span>gt</span><span>;</span><br>//ソケットの作成

$socket 🎜🎜= 🎜🎜socket_create🎜🎜(🎜🎜AF_INET🎜🎜, 🎜 🎜SOCK_STREAM🎜🎜、🎜🎜0🎜🎜 ) または die(🎜🎜"ソケットを作成できませんでした
"🎜🎜);🎜
🎜🎜🎜🎜🎜🎜最初のパラメータ「AF_INET」はドメイン名を指定するために使用されます;🎜
🎜 2 番目のパラメータ "SOCK_STREM" は、どのような 🎜🎜 クラス 🎜🎜 タイプのソケットが作成されるかを関数に伝えます (この場合、TCP 🎜🎜 クラス 🎜🎜 タイプ) 🎜
🎜 したがって、UDP ソケットを作成したい場合は、次のコードを使用できます:🎜🎜🎜🎜🎜🎜🎜[クリップボードにコピー]🎜🎜🎜🎜🎜PHP CODE:🎜🎜🎜🎜🎜// ソケットを作成します<br>🎜🎜$socket 🎜 🎜= 🎜 🎜socket_create🎜🎜(🎜🎜AF_INET🎜🎜, 🎜🎜SOCK_DGRAM🎜🎜, 🎜🎜0🎜🎜) or die(🎜🎜"ソケットを<br>作成できませんでした"🎜 🎜); 🎜<br> 🎜 🎜🎜🎜🎜4. ソケットハンドルが作成されたら、次のステップは、それを指定した🎜🎜🎜🎜アドレスと🎜🎜🎜ポートにバインドすることです。これはsocket_bind()関数を通じて実行できます。 🎜🎜🎜🎜[クリップボードにコピー]🎜🎜🎜🎜🎜PHP CODE:🎜🎜🎜🎜🎜// ソケットを指定されたアドレスとポートにバインドします<br>🎜 🎜$result 🎜🎜= 🎜🎜socket_bind 🎜🎜( 🎜🎜$socket🎜🎜、🎜🎜$host🎜🎜、🎜🎜$port🎜🎜) or die(🎜🎜"<br>ソケットにバインドできませんでした"🎜🎜 );🎜<br>🎜🎜 🎜🎜🎜5. ソケットが作成され、ポートにバインドされたら、PHP では、socket_listen() 関数を使用してソケットを開始できます。数値を指定することもできます (この例では、2 番目のパラメーター: 3)🎜🎜🎜🎜🎜🎜[クリップボードにコピー]🎜🎜🎜🎜🎜PHP CODE :🎜🎜🎜🎜🎜// 接続の待機を開始します<br>🎜🎜$result 🎜🎜= 🎜🎜socket_listen🎜🎜(🎜🎜$socket🎜🎜, 🎜🎜3🎜🎜) or die(🎜🎜「ソケット<br>リスナーをセットアップできませんでした」🎜🎜) ;🎜 <br>🎜🎜🎜🎜6. これまで、サーバーはクライアントからの接続リクエストを待つ以外は基本的に何もしませんでしたが、クライアント接続が受信されると、socket_accept() 関数が機能します。接続リクエストを受信し、サーバー間のクライアント🎜🎜🎜🎜ウェブサイト制作🎜🎜🎜🎜情報を処理するために別のサブソケットを呼び出します。 🎜🎜🎜🎜//Accept request link<br>// サブソケットを呼び出して情報を処理します<br>🎜🎜$spawn 🎜🎜= 🎜🎜socket_accept🎜🎜(🎜🎜$socket🎜🎜) or die(🎜🎜) "受信<br>接続を受け入れられませんでしたn"🎜🎜);🎜<br>🎜🎜🎜🎜🎜🎜このサブソケットは現在、後続の🎜🎜🎜🎜🎜Webページの制作に使用できます🎜🎜🎜🎜 🎜クライアントサーバー通信🎜
🎜7. 接続が確立されると、🎜🎜🎜🎜🎜🎜🎜ウェブデザイン🎜🎜 🎜🎜🎜🎜🎜 サーバーは、クライアントがこの情報を送信するのを待ちます。これはsocket_read()関数で取得でき、PHPの$input変数に代入できます。クライアント入力
🎜🎜$input 🎜🎜= 🎜🎜socket_read🎜🎜(🎜🎜$spawn🎜🎜, 🎜🎜1024 🎜🎜) or die(🎜🎜"入力を読み取れませんでした"🎜🎜);? &🎜🎜gt🎜🎜;🎜
🎜🎜

socker_read の 2 番目のパラメーターは、読み取るバイト数を指定するために使用されます。これを使用して、クライアントから取得される data のサイズを制限できます。シェルを読み取る クライアント APP
は、n、t またはを満たすまで data を開発します。 以上、PHP のソケット通信原理を内容も含めて簡単に紹介しましたが、PHP チュートリアルに興味のある友人の参考になれば幸いです。

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