ブロックされた受信とは、受信バッファーにデータがない場合、プログラムが受信機能を呼び出すときを指します。プログラムは実行を一時停止し、データが到着するまで待機してから実行を続けます。これにより、受信したデータが完全かつリアルタイムであることが保証されますが、ネットワークが良好な状態でない場合、プログラムは長い間待つことができます。
PHPのデフォルトソケットはブロッキングモードです。 socket_set_nonblockを使用して非ブロッキングに設定すると、データがない場合にsocket_recvがすぐに戻ります。
socket_set_block(リソース$ socket):bool
指定されたソケットをブロッキングモードに設定します。
socket_recv(リソース$ socket、string&$ buf、int $ len、int $ flags):int | false
ソケットからデータを受信します。ブロッキングモードでは、データがない場合、プログラムはデータが到着するのを待ちます。
次の例は、サーバーに接続した後にTCPクライアントを作成する方法を示しています。Socket_Set_Blockを使用してSocketをブロッキングモードに設定し、 Socket_Recvを使用してデータをブロックします。
<?php
// 作成するTCP socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
die("socket_create failed: " . socket_strerror(socket_last_error()) . "\n");
}
// サーバーに接続します
$server_ip = 'gitbox.net';
$server_port = 8080;
$result = socket_connect($socket, $server_ip, $server_port);
if ($result === false) {
die("socket_connect failed: " . socket_strerror(socket_last_error($socket)) . "\n");
}
// 設定socketブロッキングモードで(デフォルトでは、すでにブロックされています)
socket_set_block($socket);
echo "接続に正常に,データの受信を待っています...\n";
while (true) {
$buffer = '';
// からsocket最もブロックされたレセプション1024バイト
$bytes = socket_recv($socket, $buffer, 1024, 0);
if ($bytes === false) {
echo "socket_recv failed: " . socket_strerror(socket_last_error($socket)) . "\n";
break;
} elseif ($bytes === 0) {
// 接続が閉じます
echo "サーバーは接続を閉じます\n";
break;
} else {
echo "受け取った {$bytes} バイト数据: $buffer\n";
}
}
// 閉鎖socket
socket_close($socket);
?>
TCPソケットを作成します。
指定されたサーバーに接続します(ドメイン名はgitbox.netに置き換えられます)。
Socket_set_blockを呼び出して、ソケットがブロックしていることを確認します。
Socket_Recvを呼び出します。現在データがない場合は、データが読み取られるまでブロックして待ちます。
データを受信した後に印刷します。
サーバーが接続を閉じた場合、ループを終了してソケットを閉じます。
socket_set_blockは、 Socket_Recvを呼び出すときにデータがブロックされ、Socket_Recvがブロックされていることを確認するために、Socketをブロックモードに明示的に設定できます。
ブロッキングモードは、データのリアルタイム要件が高く、待機していないシナリオに適しています。
プログラムをブロックしないようにしたい場合は、 socket_set_nonblockを使用したり、ソケットタイムアウトを設定したりできます。
ブロッキングおよび非ブロッキングメカニズムを理解することは、さまざまなアプリケーションのニーズを満たすために、ネットワーク通信プログラムをより柔軟に設計するのに役立ちます。