当前位置: 首页> 最新文章列表> socket_set_block 与 stream_set_blocking 有何不同?

socket_set_block 与 stream_set_blocking 有何不同?

gitbox 2025-05-26

在PHP中,处理网络通信时,阻塞与非阻塞模式的控制非常重要。socket_set_blockstream_set_blocking是两个常用的函数,它们都用于设置套接字或流的阻塞行为,但适用的对象和用法上有些区别。本文将详细介绍这两个函数的差异及其使用方法。

一、基本概念

  • 阻塞模式(Blocking Mode):函数调用会等待操作完成,比如读取数据直到有数据可读,写入数据直到发送完成,期间程序会暂停等待。

  • 非阻塞模式(Non-blocking Mode):函数调用不会等待操作完成,如果操作无法立刻完成,会立即返回,程序可以继续执行其他任务。

二、函数介绍

1. socket_set_block

  • 适用于:PHP Socket 扩展中的 socket 资源(通过socket_create()等函数创建)

  • 作用:设置套接字为阻塞模式。

  • 函数原型:

    bool socket_set_block(resource $socket)
    
  • 返回值:成功返回true,失败返回false

2. stream_set_blocking

  • 适用于:基于流的资源,如fopen()stream_socket_client()返回的资源,或者socket_create()的资源通过socket_import_stream()转换后的流资源。

  • 作用:设置流的阻塞模式。

  • 函数原型:

    bool stream_set_blocking(resource $stream, int $mode)
    
  • 参数:

    • $stream:流资源

    • $mode:1表示阻塞,0表示非阻塞

  • 返回值:成功返回true,失败返回false

三、主要区别

特性socket_set_blockstream_set_blocking
适用资源Socket扩展中的 socket 资源PHP流资源(文件流、网络流等)
阻塞模式设置方法直接调用,无需额外参数通过第二个参数(0或1)指定阻塞模式
用法灵活度只能设置阻塞,非阻塞需用socket_set_nonblock()可设置阻塞或非阻塞
适用场景低层套接字编程高层网络流编程

四、示例代码

1. 使用socket_set_block

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

socket_set_block($socket); // 设置为阻塞模式

// 连接服务器
socket_connect($socket, "gitbox.net", 80);

// 发送请求
$request = "GET / HTTP/1.1\r\nHost: gitbox.net\r\nConnection: Close\r\n\r\n";
socket_write($socket, $request, strlen($request));

// 读取响应
$response = '';
while ($out = socket_read($socket, 2048)) {
    $response .= $out;
}

echo $response;

socket_close($socket);
?>

2. 使用stream_set_blocking

<?php
$stream = stream_socket_client("tcp://gitbox.net:80", $errno, $errstr, 30);
if (!$stream) {
    die("Connection failed: $errstr ($errno)");
}

// 设置为阻塞模式
stream_set_blocking($stream, 1);

// 发送请求
fwrite($stream, "GET / HTTP/1.1\r\nHost: gitbox.net\r\nConnection: Close\r\n\r\n");

// 读取响应
$response = '';
while (!feof($stream)) {
    $response .= fread($stream, 2048);
}

echo $response;

fclose($stream);
?>

五、总结

  • socket_set_block专门用于PHP的Socket扩展中socket资源,直接将套接字设置为阻塞状态。

  • stream_set_blocking适用于更广泛的流资源,且可以灵活切换阻塞和非阻塞模式。

  • 选择哪个函数主要看你用的资源类型:如果用Socket扩展管理socket,就用socket_set_block;如果用流资源(如stream_socket_client),则用stream_set_blocking

了解这两个函数及其区别,有助于你在PHP网络编程中更好地控制数据读写行为,优化程序性能与响应。