PHPでは、ソケットプログラミングは、ネットワーク通信を実現するための基本的な手段の1つです。デフォルトでは、ソケットは非ブロッキングである可能性があります。つまり、データがない場合、データが到着するのを待つ代わりに、読み取り操作がすぐに戻ります。ブロッキングソケットは、データが読み取られるまでデータを読み取る間、プログラムを待機させます。これは、単純な同期チャットプログラムの実装に適しています。
この記事では、PHPのsocket_set_block関数を使用してソケットをブロッキングモードに設定し、これに基づいて単純なブロッキングチャットプログラムの例を実装する方法を紹介します。
ブロッキングソケットとは、読み取りまたは書き込み操作の実行時にデータが到着するか、操作が完了するまで、プログラムが一時停止し、待機することを指します。この方法は簡単に実装してロジックをクリアすることができ、初心者や小規模なチャットアプリケーションに最適です。
対照的に、非ブロッキングソケットにはイベントポーリングまたは非同期操作が必要です。これらは論理的に複雑ですが、高性能の要件により適しています。
socket_set_blockは、ソケットブロッキングモードを設定するPHPの関数です。この関数を呼び出すと、ソケットはブロッキング状態に切り替わります。
関数プロトタイプ:
bool socket_set_block(resource $socket)
$ソケット:設定する必要があるソケットリソース
返品値:成功のためにtrueを返す、失敗のためにfalseを返す
以下は、単純なブロッキングソケットチャットサーバーの例です。クライアントは接続後にメッセージを送信でき、サーバーはそれを受信した後に単純にエコーします。
<?php
$host = "0.0.0.0";
$port = 12345;
// 作成する Socket
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($sock === false) {
die("socket_create() 失敗: " . socket_strerror(socket_last_error()));
}
// アドレスとポートをバインドします
if (!socket_bind($sock, $host, $port)) {
die("socket_bind() 失敗: " . socket_strerror(socket_last_error($sock)));
}
// ポートを聞いてください
if (!socket_listen($sock, 5)) {
die("socket_listen() 失敗: " . socket_strerror(socket_last_error($sock)));
}
echo "サーバーの起動,モニター {$host}:{$port}...\n";
// クライアント接続を受け入れます
$client = socket_accept($sock);
if ($client === false) {
die("socket_accept() 失敗: " . socket_strerror(socket_last_error($sock)));
}
// クライアントのセットアップ Socket ブロッキングモードで
socket_set_block($client);
echo "クライアントの接続が成功しました,メッセージを待っています...\n";
while (true) {
// クライアントデータの読み取りをブロックします
$data = socket_read($client, 2048, PHP_NORMAL_READ);
if ($data === false) {
echo "socket_read() 失敗: " . socket_strerror(socket_last_error($client)) . "\n";
break;
}
$data = trim($data);
if ($data === '') {
continue;
}
echo "クライアントメッセージを受け取りました: $data\n";
if ($data === 'quit') {
echo "クライアントの切断\n";
break;
}
// メッセージをクライアントにエコーします
$response = "サーバーが受信されました: $data\n";
socket_write($client, $response, strlen($response));
}
// 閉鎖 Socket 接続する
socket_close($client);
socket_close($sock);
?>
上記のコードをserver.phpとして保存し、コマンドラインで実行します。
php server.php
Telnetまたは他のTCPクライアントを使用して接続します。
telnet gitbox.net 12345
(この例では、ポートは12345で、ドメイン名の例がgitbox.netに変更されます)
メッセージを入力すると、サーバーは入力をブロックして待機し、メッセージを受信した後に確認します。
QUITを入力して切断します。
socket_set_blockを使用すると、ソケットをブロッキングモードに設定するのが非常に便利になり、シンプルな同期チャットロジックが可能になります。ブロッキングプログラミングは、初心者がネットワークプログラミングを迅速に開始するのに適していますが、並行性のシナリオでは、非ブロッキングまたは非同期方法がより効率的です。
PHPソケットプログラミングの詳細については、以下をご覧ください。
https://gitbox.net/manual/socket