現在の位置: ホーム> 最新記事一覧> socket_set_blockとsocket_set_nonblockを正しく切り替える方法

socket_set_blockとsocket_set_nonblockを正しく切り替える方法

gitbox 2025-05-29

PHPを使用したプログラミングネットワークの場合、 socket_set_block()socket_set_nonblock()は、ソケットがブロックモードで動作するか非ブロックモードで動作するかを制御する2つの非常に重要な関数です。これらの2つのモードを合理的に切り替えると、ネットワークI/Oがより柔軟に対処し、プログラムの効率と応答性を向上させることができます。

ブロッキングモードと非ブロッキングモードの違い

ブロッキングモード(デフォルト):このモードでは、ソケット操作( socket_read()socket_accept()など)は、データが読み取られるか、接続が完了するまで待機します。この方法は簡単に記述できますが、並行性のシナリオでは、スレッドまたはプロセスの閉塞を引き起こし、全体的なパフォーマンスを低下させる可能性があります。

非ブロッキングモード:逆に、非ブロッキングモードでのソケット操作はすぐに戻ります。操作をすぐに完了できない場合(読み取るデータがない場合)、関数はfalseを返し、エラーコードをeagainまたはewouldblockに設定します。

正しく使用するために切り替える方法は?

ブロッキング状態とソケットの非ブロッキング状態を切り替え、アプリケーションシナリオと組み合わせて使用​​する方法を示す簡単な例を次に示します。

 <?php
$host = 'gitbox.net';
$port = 8080;

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
    die("socket_create() failed: " . socket_strerror(socket_last_error()));
}

// 非ブロッキングモードに設定します,接続してみてください
socket_set_nonblock($socket);

$connected = @socket_connect($socket, $host, $port);
if (!$connected) {
    $err = socket_last_error($socket);
    if ($err !== SOCKET_EINPROGRESS && $err !== SOCKET_EALREADY) {
        die("socket_connect() failed: " . socket_strerror($err));
    }
}

// 使用 select 接続が成功しているかどうかを確認してください
$write = [$socket];
$null = [];
if (socket_select($null, $write, $null, 5) > 0) {
    // ブロッキングモードに戻ります,後続のデータ送信と受信に使用されます
    socket_set_block($socket);

    // データの送信と受信を開始します
    socket_write($socket, "GET / HTTP/1.1\r\nHost: $host\r\n\r\n");
    $response = socket_read($socket, 2048);
    echo "Response: " . $response;
} else {
    die("Connection timeout or failed");
}

socket_close($socket);
?>

説明する:

  1. 非ブロッキング接続socket_set_nonblock()を使用して、接続操作がプログラムの実行をブロックするのを防ぎます。

  2. socket_select()を使用して、ソケットが書き出すのを待つ:これは、接続が成功したかどうかを検出する一般的なトリックです。

  3. ブロッキングモードに戻りますsocket_set_block()を使用して、接続が確立された直後にブロッキングモードに戻り、後続のデータ相互作用を促進します。

  4. リクエストと読み取り応答:この時点でのソケットはブロッキングモードで動作します。これにより、完全なサーバー応答の読み取りが容易になります。

スイッチモードはいつですか?

  • 複数の接続要求が迅速に開始される必要がある場合は、非ブロッキングモードを使用します。

  • タイムアウト制御など、特定の操作が無限に待たないようにする必要があります。

  • 接続または特定のフェーズを完了したら、ブロッキングモードに戻り、コード処理ロジックを簡素化します。

注意すべきこと

  • 非ブロッキングモードでは、すべてのソケット操作がエラーチェックを受ける必要があります。

  • Socket_Select()は、非ブロッキングソケットプログラミングの重要なツールです。

  • スイッチングモードは、静的ではなく、操作段階に従って実行する必要があります。

Blockingモードと非ブロッキングモードを適度に切り替えることにより、PHPソケットプログラミングはパフォーマンスと安定性を考慮するだけでなく、複雑なネットワーク通信のニーズにも適切に対応できます。