socket_export_stream関数の関数は、生のソケットリソースを標準のPHPストリーム関数と互換性のあるストリームリソースに変換することです。これにより、基礎となるソケット接続がFreadなどのストリーム読み取り機能で動作し、データの読み取り値をより便利にすることができます。
<span><span>resource </span><span><span class="hljs-title function_ invoke__">socket_export_stream</span></span><span> ( resource </span><span><span class="hljs-variable">$socket</span></span><span> )
</span></span>
戻り値は標準のストリームリソースであるため、 FREAD 、 FWRITE 、またはその他のストリーム操作関数を使用して、データを読み書きすることができます。
FREADは、ファイルポインターまたはストリームから指定された数のバイト数のデータを読み取るために使用される関数です。 Fopen 、 socket_export_streamなどと組み合わせて、ストリーム内のデータを読み取るためによく使用されます。
<span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-title function_ invoke__">fread</span></span><span> ( resource </span><span><span class="hljs-variable">$handle</span></span><span> , </span><span><span class="hljs-keyword">int</span></span><span> </span><span><span class="hljs-variable">$length</span></span><span> )
</span></span>
パラメーター:
$ハンドルはストリームリソースであり、 socket_export_streamによって返されるストリームリソースです。
$の長さは、読み取るバイト数です。
Freadは読み取りコンテンツを返し、データを読み取れない場合、空の文字列を返します。
サーバーと通信するTCPクライアントの簡単なインスタンスを作成します。クライアントはサーバーに接続し、ソケットを介してリクエストを送信し、 Freadを使用してサーバーからの応答を読み取ります。
<span><span><span class="hljs-comment">// サーバー側のコード</span></span><span>
</span><span><span class="hljs-variable">$host</span></span><span> = </span><span><span class="hljs-string">'127.0.0.1'</span></span><span>;
</span><span><span class="hljs-variable">$port</span></span><span> = </span><span><span class="hljs-number">8080</span></span><span>;
</span><span><span class="hljs-comment">// 作成する socket リソース</span></span><span>
</span><span><span class="hljs-variable">$server</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_create</span></span><span>(AF_INET, SOCK_STREAM, SOL_TCP);
</span><span><span class="hljs-title function_ invoke__">socket_bind</span></span><span>(</span><span><span class="hljs-variable">$server</span></span><span>, </span><span><span class="hljs-variable">$host</span></span><span>, </span><span><span class="hljs-variable">$port</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">socket_listen</span></span><span>(</span><span><span class="hljs-variable">$server</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"サーバーが開始されます,クライアント接続を待っています...\n"</span></span><span>;
</span><span><span class="hljs-comment">// クライアント接続を待っています</span></span><span>
</span><span><span class="hljs-variable">$client</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_accept</span></span><span>(</span><span><span class="hljs-variable">$server</span></span><span>);
</span><span><span class="hljs-comment">// クライアントにデータを送信します</span></span><span>
</span><span><span class="hljs-variable">$message</span></span><span> = </span><span><span class="hljs-string">"Hello from server!"</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">socket_write</span></span><span>(</span><span><span class="hljs-variable">$client</span></span><span>, </span><span><span class="hljs-variable">$message</span></span><span>, </span><span><span class="hljs-title function_ invoke__">strlen</span></span><span>(</span><span><span class="hljs-variable">$message</span></span><span>));
</span><span><span class="hljs-comment">// 接続を閉じます</span></span><span>
</span><span><span class="hljs-title function_ invoke__">socket_close</span></span><span>(</span><span><span class="hljs-variable">$client</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">socket_close</span></span><span>(</span><span><span class="hljs-variable">$server</span></span><span>);
</span></span>
<span><span><span class="hljs-comment">// クライアントコード</span></span><span>
</span><span><span class="hljs-variable">$host</span></span><span> = </span><span><span class="hljs-string">'127.0.0.1'</span></span><span>;
</span><span><span class="hljs-variable">$port</span></span><span> = </span><span><span class="hljs-number">8080</span></span><span>;
</span><span><span class="hljs-comment">// 作成する socket リソース</span></span><span>
</span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_create</span></span><span>(AF_INET, SOCK_STREAM, SOL_TCP);
</span><span><span class="hljs-title function_ invoke__">socket_connect</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-variable">$host</span></span><span>, </span><span><span class="hljs-variable">$port</span></span><span>);
</span><span><span class="hljs-comment">// 意思 socket リソース转换为流リソース</span></span><span>
</span><span><span class="hljs-variable">$stream</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_export_stream</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span><span><span class="hljs-comment">// Streamからデータを読み取ります</span></span><span>
</span><span><span class="hljs-variable">$response</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fread</span></span><span>(</span><span><span class="hljs-variable">$stream</span></span><span>, </span><span><span class="hljs-number">1024</span></span><span>); </span><span><span class="hljs-comment">// 最も読んでください 1024 バイトデータ</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"サーバーの応答: "</span></span><span> . </span><span><span class="hljs-variable">$response</span></span><span> . </span><span><span class="hljs-string">"\n"</span></span><span>;
</span><span><span class="hljs-comment">// 接続を閉じます</span></span><span>
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$stream</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">socket_close</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span></span>
サーバー側:最初に、TCPソケットを作成し、ローカルアドレスとポート8080にバインドされています。サーバーは、クライアントが接続するのを待っている間に聞きます。クライアント接続がある場合、接続を受け入れてメッセージを送信し、接続を閉じます。
クライアント:クライアントは最初にTCPソケットを作成し、サーバーに接続します。次に、 socket_export_streamを使用して、ソケットをストリームリソースに変換します。次に、 FREAD機能を介してサーバーから返されたデータを読み取ります。
ネットワークプログラミングでは、データの読み取り時にしばしば発生する問題は、データの不完全な読み取りです。たとえば、サーバーから送信されるデータの量は、一度に読み取られるバイト数よりもはるかに大きい場合があります。この時点で、すべてのデータが読み取られるまで、いくつかのデータスプライシング作業を行う必要があります。
<span><span><span class="hljs-variable">$response</span></span><span> = </span><span><span class="hljs-string">''</span></span><span>;
</span><span><span class="hljs-keyword">while</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">feof</span></span><span>(</span><span><span class="hljs-variable">$stream</span></span><span>)) {
</span><span><span class="hljs-variable">$chunk</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fread</span></span><span>(</span><span><span class="hljs-variable">$stream</span></span><span>, </span><span><span class="hljs-number">1024</span></span><span>); </span><span><span class="hljs-comment">// それぞれ読みます 1024 バイト</span></span><span>
</span><span><span class="hljs-variable">$response</span></span><span> .= </span><span><span class="hljs-variable">$chunk</span></span><span>;
}
</span></span>
PHPソケットはデフォルトでブロックされています。つまり、 Freadは、戻る前にデータが到着するまで待つ場合があります。データを非ブロッキングする必要がある場合は、 socket_set_nonblockを使用してソケットを非ブロッキングモードに設定できるため、データが完全に読み取られていなくても、 Freadはすぐに戻ります。
<span><span><span class="hljs-title function_ invoke__">socket_set_nonblock</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
</span></span>
socket_export_streamおよびfread関数を介して、ソケットデータストリームをより簡単に操作できます。これらの2つの機能を組み合わせて使用して、ファイルストリームを操作するなどのリモートサーバーからネットワークデータを単純に読み取ることができます。実際の開発では、このアプローチは、リアルタイムおよび継続的なデータ相互作用の処理に非常に適しています。
この記事の例を通して、ソケットから得られた実際の開発データとプロセスデータのためにこれら2つの機能を組み合わせる方法をよりよく理解できることを願っています。