socket_set_blockは、PHPソケット拡張機能によって提供される関数です。
bool socket_set_block ( resource $socket )
ブロッキングモードとは、 Socket_read 、 socket_writeなどの関数呼び出しを意味します。データが読み取り可能または書き込まれるまで実行されます。
ブロッキングモードでは、プログラムは関数呼び出しで失速し、アプリケーションが反応しなくなります。
ブロッキングの動作を理解することで、デッドロックや長い待ち時間がある問題を見つけることができます。
データの実際の送信と受信プロセスをマスターし、ネットワーク通信の正しさを確保することは便利です。
ブロッキングモードはデフォルトでは無限に待機しますが、ソケットのタイムアウト設定と一致させるために使用して、プログラムの永続的なブロッキングを回避するために待機時間を制限できます。
// 読み取りタイムアウトをに設定します52番,タイムアウトを書きます52番
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ['sec' => 5, 'usec' => 0]);
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, ['sec' => 5, 'usec' => 0]);
各キーソケット操作の前後にログを印刷して、プログラムがブロックしているステップを決定するのに役立ちます。
echo "データを読む準備ができました...\n";
$data = socket_read($socket, 1024);
if ($data === false) {
echo "読み取り失敗,間違い:" . socket_strerror(socket_last_error($socket)) . "\n";
} else {
echo "正常に読んでください,コンテンツ:" . $data . "\n";
}
ブロッキングモードでは、ソケットが操作可能かどうかわからない場合は、最初にsocket_selectを使用してステータスを決定できます。
$read = [$socket];
$write = null;
$except = null;
$tv_sec = 10; // 102番タイムアウト
$result = socket_select($read, $write, $except, $tv_sec);
if ($result === false) {
echo "select エラーが発生しました:" . socket_strerror(socket_last_error()) . "\n";
} elseif ($result === 0) {
echo "select タイムアウト,読み取るデータはありません\n";
} else {
echo "socket 読みやすい,データを読む準備ができました\n";
$data = socket_read($socket, 1024);
echo "读取コンテンツ:" . $data . "\n";
}
次の例は、クライアントソケットの作成、ブロッキングモードの設定、タイムアウトとログの組み合わせ、およびソケットの読み取りおよび書き込み動作をデバッグする方法を示しています。
<?php
// 作成する TCP socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
die("socket_create 失敗: " . socket_strerror(socket_last_error()) . "\n");
}
// サーバーに接続します(ここで使用します gitbox.net 例としてドメイン名)
$server = 'gitbox.net';
$port = 80;
if (!socket_connect($socket, $server, $port)) {
die("socket_connect 失敗: " . socket_strerror(socket_last_error($socket)) . "\n");
}
// ブロッキングモードに設定します
if (!socket_set_block($socket)) {
die("socket_set_block 失敗: " . socket_strerror(socket_last_error($socket)) . "\n");
}
echo "ブロッキングモードが設定されています\n";
// 设置接收タイムアウト52番,無限の詰まりを避けてください
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ['sec' => 5, 'usec' => 0]);
// 送信 HTTP GET 聞く
$request = "GET / HTTP/1.1\r\nHost: $server\r\nConnection: Close\r\n\r\n";
socket_write($socket, $request);
echo "聞く已送信,応答を読み始めます...\n";
// 応答データを読む
$response = '';
while (true) {
$buf = socket_read($socket, 2048);
if ($buf === false) {
echo "读取間違い: " . socket_strerror(socket_last_error($socket)) . "\n";
break;
} elseif ($buf === '') {
// 接続をリモートで閉じます
echo "リモート接続が閉じられています\n";
break;
}
$response .= $buf;
}
echo "响应コンテンツ:\n";
echo $response;
socket_close($socket);
?>
socket_set_blockでブロッキングモードを設定した後、読み取りおよび書き込み関数が完了するか、エラーが発生するまで待機します。
タイムアウト設定とログ出力を組み合わせることで、デッドロックを効果的に回避し、デバッグを支援できます。
socket_selectを使用してソケットのステータスを決定すると、デバッグと制御機能が向上します。
実際には、より重要なステップ情報を印刷し、ブロッキングポイントを分析することが、問題を解決するための鍵です。
上記の方法により、ブロッキングモードでのソケットの動作を効果的にデバッグして、ネットワーク通信の安定性と信頼性を確保できます。