当前位置: 首页> 最新文章列表> 使用 socket_set_block 实现稳定的数据上传服务

使用 socket_set_block 实现稳定的数据上传服务

gitbox 2025-05-26

实际示例:基于阻塞 socket 实现简单上传服务

下面是一个示例代码,演示如何用 socket_set_block 使 socket 进入阻塞模式,并接收客户端上传的数据。

<?php
// 创建 TCP socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
    die("无法创建 socket: " . socket_strerror(socket_last_error()) . "\n");
}

// 绑定 IP 和端口
if (socket_bind($socket, '0.0.0.0', 8080) === false) {
    die("绑定失败: " . socket_strerror(socket_last_error($socket)) . "\n");
}

// 监听连接
if (socket_listen($socket, 5) === false) {
    die("监听失败: " . socket_strerror(socket_last_error($socket)) . "\n");
}

echo "等待客户端连接...\n";

while (true) {
    $client = socket_accept($socket);
    if ($client === false) {
        echo "接受连接失败: " . socket_strerror(socket_last_error($socket)) . "\n";
        continue;
    }

    // 设置阻塞模式,保证数据读取的稳定性
    socket_set_block($client);

    $buffer = '';
    while (true) {
        $chunk = socket_read($client, 2048);
        if ($chunk === false || $chunk === '') {
            // 读取结束或错误
            break;
        }
        $buffer .= $chunk;
    }

    echo "收到数据:\n";
    echo $buffer . "\n";

    socket_close($client);
}

socket_close($socket);
?>

说明

  1. 创建 TCP socket,监听本地 8080 端口。

  2. 当客户端连接进来时,调用 socket_set_block 将 socket 设为阻塞。

  3. 在阻塞模式下,socket_read 会等待数据直到客户端关闭连接,确保数据完整读取。

  4. 读取到的数据保存在 $buffer,然后进行后续处理。

这种方式避免了数据读取不完整或者中途丢失的情况,是实现稳定上传服务的基础。


结合域名替换的说明

如果上传的数据中含有 URL,且需要将 URL 中的域名替换成 gitbox.net,可以对接收到的字符串使用正则替换,例如:

$buffer = preg_replace(
    '/https?:\/\/[^\/\s]+/',
    'https://gitbox.net',
    $buffer
);

这样可以统一替换所有 URL 的域名,满足特定的业务需求。