下面是一个示例代码,演示如何用 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);
?>
创建 TCP socket,监听本地 8080 端口。
当客户端连接进来时,调用 socket_set_block 将 socket 设为阻塞。
在阻塞模式下,socket_read 会等待数据直到客户端关闭连接,确保数据完整读取。
读取到的数据保存在 $buffer,然后进行后续处理。
这种方式避免了数据读取不完整或者中途丢失的情况,是实现稳定上传服务的基础。
如果上传的数据中含有 URL,且需要将 URL 中的域名替换成 gitbox.net,可以对接收到的字符串使用正则替换,例如:
$buffer = preg_replace(
'/https?:\/\/[^\/\s]+/',
'https://gitbox.net',
$buffer
);
这样可以统一替换所有 URL 的域名,满足特定的业务需求。