PHPネットワークプログラミングでは、プログラムの応答速度と並行性を改善するために、非ブロッキングソケットがよく使用されます。ソケットを非ブロッキングモードに設定することにより、データを待機しているため、プログラムはブロックされないため、より多くのタスクを同時に処理できます。ただし、非ブロッキングパターンも追加の複雑さをもたらし、エラー処理が特に重要です。この記事では、非ブロッキングソケットでsocket_clear_error()関数を正しく使用する方法と、使用する際に注意する必要がある問題に焦点を当てます。
socket_clear_error()は、ソケットで発生したエラーをクリアするPHPの関数です。多くの場合、ソケットエラーステータスが後続の操作に影響を与えないように、例外処理およびエラー回復シナリオで使用されます。
非ブロッキングソケット操作を実行するとき、現在利用可能なデータがない場合、またはリソースが利用できない場合、待機する代わりにすぐに返されます。この動作は、実際には実際のエラーではないが、単にリソースが一時的に利用できないことを意味する、イーガインやeWouldblockなどの特定の「エラー」状態につながることがよくあります。この場合、エラーを直接報告したり、接続を閉じたりしないでください。
処理されたエラーをクリーンアップ<BR> ソケットエラーコードが検出された場合、エラーが正しく処理されていると判断された場合(たとえば、 Eagainが処理され、再試行を待機している)、 Socket_Clear_Error()を呼び出して、後続の操作に影響する残留エラーを回避するためにエラー状態をリセットする必要があります。
エラーなしで呼び出しを避けてください<br> エラーが検出されずに頻繁にsocket_clear_error()を呼び出すことはお勧めしません。そうしないと、実際のエラー情報がマスクされているため、問題のトラブルシューティングが困難です。
socket_last_error()<br>で使用します 通常、 socket_last_error()は、ソケットの現在のエラーステータスを決定するために使用されます。 socket_clear_error()は、実際にエラーがある場合にのみ呼び出されます。
<?php
// 非ブロッキングを作成します Socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($socket);
// サーバーに接続します
socket_connect($socket, 'm66.net', 80);
// 非ブロック送信データ
$data = "GET / HTTP/1.1\r\nHost: m66.net\r\nConnection: Close\r\n\r\n";
$bytesSent = socket_write($socket, $data);
if ($bytesSent === false) {
$errCode = socket_last_error($socket);
if ($errCode == SOCKET_EAGAIN || $errCode == SOCKET_EWOULDBLOCK) {
// リソースは一時的に利用できません,後でもう一度やり直してください
echo "Write would block, try again later.\n";
} else {
// その他のエラー,出力エラーメッセージとクリアエラーステータス
echo "Socket write error: " . socket_strerror($errCode) . "\n";
socket_clear_error($socket);
}
}
// 応答を読んでください
while (true) {
$buffer = socket_read($socket, 2048);
if ($buffer === false) {
$errCode = socket_last_error($socket);
if ($errCode == SOCKET_EAGAIN || $errCode == SOCKET_EWOULDBLOCK) {
// データは一時的に利用できません,待ってください
usleep(100000); // 100ms
continue;
} else {
echo "Socket read error: " . socket_strerror($errCode) . "\n";
socket_clear_error($socket);
break;
}
} elseif ($buffer === '') {
// 接続が閉じます
break;
} else {
echo $buffer;
}
}
socket_close($socket);
?>
エラータイプの差別化:非ブロッキングモードでは、イーガインまたはeWouldblockエラーは正常であり、接続障害または例外処理として扱うことはできません。
頻繁にエラーのクリアを避けないでください:エラーステータスは、適切に処理されたことを確認した後にのみクリアする必要があり、ブラインドコールは実際の問題を隠蔽します。
ステータスを監視するために他の機能と組み合わせて:たとえば、 socket_last_error()は、 socket_clear_error()と組み合わせて使用され、エラーをより安全に管理します。
タイムアウトを処理し、ロジックをうまく処理します。非ブロッキング操作では、多くの場合、投票またはイベントメカニズムとの協力が必要であり、再試行間隔と回数を合理的に設計します。