PHPでは、 FSOCOPEN関数は、ソケット接続を作成するために一般的に使用される機能であり、リモートサーバーとデータを通信できます。 FSOCCKOPENを使用すると、単純なソケットデータ転送を実装できます。これは、低レベルのネットワーク操作を必要とするアプリケーションに非常に役立ちます。この記事では、 FSoCopenを使用してデータ送信を実装し、使用中に使用できるヒントを共有する方法について説明します。
FSOCCKOPEN関数は、ネットワーク接続を開くために使用され、TCPまたはUDPソケットの作成に使用できます。最も基本的な関数プロトタイプは次のとおりです。
<span><span>resource </span><span><span class="hljs-title function_ invoke__">fsockopen</span></span><span> ( </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$hostname</span></span><span> , </span><span><span class="hljs-keyword">int</span></span><span> </span><span><span class="hljs-variable">$port</span></span><span> [, </span><span><span class="hljs-keyword">int</span></span><span> &</span><span><span class="hljs-variable">$errno</span></span><span> [, </span><span><span class="hljs-keyword">string</span></span><span> &</span><span><span class="hljs-variable">$errstr</span></span><span> [, </span><span><span class="hljs-keyword">float</span></span><span> </span><span><span class="hljs-variable">$timeout</span></span><span> = </span><span><span class="hljs-title function_ invoke__">ini_get</span></span><span>(</span><span><span class="hljs-string">"default_socket_timeout"</span></span><span>) ]]] )
</span></span>
$ hostname :宛先ホスト名またはIPアドレス。
$ポート:ターゲットポート番号。
$ errnoおよび$ errstr :エラーメッセージをキャプチャするオプションのパラメーター。
$タイムアウト:オプションの接続タイムアウト、秒単位。
使用の簡単な例:
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-variable">$host</span></span><span> = </span><span><span class="hljs-string">'www.example.com'</span></span><span>;
</span><span><span class="hljs-variable">$port</span></span><span> = </span><span><span class="hljs-number">80</span></span><span>;
</span><span><span class="hljs-variable">$timeout</span></span><span> = </span><span><span class="hljs-number">30</span></span><span>; </span><span><span class="hljs-comment">// タイムアウト時間を設定します 30 2番</span></span><span>
</span><span><span class="hljs-comment">// 使用 fsockopen 接続を確立します</span></span><span>
</span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fsockopen</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-variable">$errno</span></span><span>, </span><span><span class="hljs-variable">$errstr</span></span><span>, </span><span><span class="hljs-variable">$timeout</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$socket</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"間違い: <span class="hljs-subst">$errno</span></span></span><span> - </span><span><span class="hljs-subst">$errstr</span></span><span><br />\n";
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"正常に接続されています <span class="hljs-subst">$host</span></span></span><span>:</span><span><span class="hljs-subst">$port</span></span><span><br />\n";
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
}
</span><span><span class="hljs-meta">?></span></span><span>
</span></span>
接続が確立されたら、サーバーでデータ転送を開始できます。 HTTPプロトコル通信の場合、通常、リクエストヘッダーを送信する必要があり、サーバーは対応するデータに応答します。これが簡単なHTTPリクエストの例です。
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-variable">$host</span></span><span> = </span><span><span class="hljs-string">'www.example.com'</span></span><span>;
</span><span><span class="hljs-variable">$port</span></span><span> = </span><span><span class="hljs-number">80</span></span><span>;
</span><span><span class="hljs-variable">$timeout</span></span><span> = </span><span><span class="hljs-number">30</span></span><span>;
</span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fsockopen</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-variable">$errno</span></span><span>, </span><span><span class="hljs-variable">$errstr</span></span><span>, </span><span><span class="hljs-variable">$timeout</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$socket</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"間違い: <span class="hljs-subst">$errno</span></span></span><span> - </span><span><span class="hljs-subst">$errstr</span></span><span><br />\n";
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-comment">// 建てる HTTP ヘッダーをリクエストします</span></span><span>
</span><span><span class="hljs-variable">$request</span></span><span> = </span><span><span class="hljs-string">"GET / HTTP/1.1\r\n"</span></span><span>;
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"Host: <span class="hljs-subst">$host</span></span></span><span>\r\n";
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"Connection: close\r\n"</span></span><span>;
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"\r\n"</span></span><span>;
</span><span><span class="hljs-comment">// リクエストを送信します</span></span><span>
</span><span><span class="hljs-title function_ invoke__">fwrite</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-variable">$request</span></span><span>);
</span><span><span class="hljs-comment">// サーバーの応答を受信して出力します</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">$socket</span></span><span>)) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">fgets</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-number">128</span></span><span>);
}
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>);
}
</span><span><span class="hljs-meta">?></span></span><span>
</span></span>
上記のコードでは、 FSOCOPENを使用して接続を確立し、 FWRITE関数を介してHTTPリクエストヘッダーをサーバーに送信し、 FGETS関数を使用してサーバーによって返されたデータを読み取ります。最後に、 fclose経由でソケット接続を閉じます。
ネットワークプログラミングでは、特にリモートサーバーと対話する場合、合理的なタイムアウトの設定が非常に重要です。接続タイムアウトは、 FSOCOPENの$タイムアウトパラメーターを介して制御できます。設定したタイムアウトが短すぎると、早期の接続中断を引き起こす可能性があります。長すぎると、接続できないときにプログラムが停止される可能性があります。通常、タイムアウトを30秒以内に設定することをお勧めします。
<span><span><span class="hljs-variable">$timeout</span></span><span> = </span><span><span class="hljs-number">10</span></span><span>; </span><span><span class="hljs-comment">// にタイムアウトを設定します 10 2番</span></span><span>
</span></span>
fsocckopen関数の返品値はリソースタイプ(ソケット接続のハンドル)であり、接続が失敗するとfalseが返されます。エラーを避けてそれらを処理するには、詳細なレコードのエラーコード$ errnoとエラーメッセージ$ errstrを使用することをお勧めします。
<span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$socket</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"接続に失敗しました:<span class="hljs-subst">$errno</span></span></span><span> - </span><span><span class="hljs-subst">$errstr</span></span><span><br />\n";
</span><span><span class="hljs-keyword">exit</span></span><span>;
}
</span></span>
HTTPリクエストの送信に加えて、 FSoCopenはFTP、SMTP、POP3などの他のプロトコルからデータを送信するためにも使用できます。プロトコルに関係なく、コアアイデアはFWRITE 、 FREAD 、またはFGETSを介してデータを送信して応答を取得することです。プロトコルによっては、データ形式が変更される場合があります。データを送信する前に、ターゲットプロトコルのリクエスト形式に精通することをお勧めします。
場合によっては、HTTPの永続的な接続を介して達成できるサーバーとの長期的な接続を維持することが望ましい場合があります(Keep-Alive)。接続を追加することで:リクエストヘッダーに保持することで、複数のリクエスト間で接続を除外しておくことができます。
<span><span><span class="hljs-variable">$request</span></span><span> = </span><span><span class="hljs-string">"GET / HTTP/1.1\r\n"</span></span><span>;
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"Host: <span class="hljs-subst">$host</span></span></span><span>\r\n";
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"Connection: keep-alive\r\n"</span></span><span>;
</span><span><span class="hljs-variable">$request</span></span><span> .= </span><span><span class="hljs-string">"\r\n"</span></span><span>;
</span></span>
プロキシサーバーを介してターゲットサーバーと通信する必要がある場合があります。この時点で、プロキシサーバーのアドレスとポートをターゲットサーバーに直接接続する代わりに、 fsocopenに渡すことができます。
<span><span><span class="hljs-variable">$proxy</span></span><span> = </span><span><span class="hljs-string">'proxy.example.com'</span></span><span>;
</span><span><span class="hljs-variable">$proxyPort</span></span><span> = </span><span><span class="hljs-number">8080</span></span><span>;
</span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fsockopen</span></span><span>(</span><span><span class="hljs-variable">$proxy</span></span><span>, </span><span><span class="hljs-variable">$proxyPort</span></span><span>, </span><span><span class="hljs-variable">$errno</span></span><span>, </span><span><span class="hljs-variable">$errstr</span></span><span>, </span><span><span class="hljs-variable">$timeout</span></span><span>);
</span></span>
プロキシサーバーには特定の認証情報(ユーザー名やパスワードなど)が必要になる場合があり、現時点では、プロキシプロトコルの要件に従ってリクエストヘッダーを構築する必要があります。
FSOCCKOPENは、PHPの非常に強力な機能であり、低レベルのネットワーク通信に適しています。データをリモートサーバーと交換する必要がある場合、 FSoCopenは直接的で柔軟な方法を提供します。基本的な使用方法、タイムアウト設定、エラー処理、および共通プロトコルの伝送手法のマスタリングは、ソケットデータ送信をより効率的に実現するのに役立ちます。実際のアプリケーションでは、要件に応じてパラメーターを調整し、ネットワークリクエストの安定性を確保することを忘れないでください。