本文目录导读:

- 使用
stream_socket_server()(基础方案) - 使用
pcntl多进程方案 - 使用 Swoole 扩展(推荐)
- 完整的客户端测试代码
- 使用 Workerman(另一个常见方案)
- 性能对比
- 安装建议
- 注意事项
我来详细介绍如何在PHP中创建TCP服务器,包含多种实现方案:
使用 stream_socket_server()(基础方案)
这是PHP内置的最简单方式:
<?php
// 创建TCP服务器
$server = stream_socket_server(
"tcp://0.0.0.0:8080",
$errno,
$errstr
);
if (!$server) {
die("无法创建服务器: $errstr ($errno)");
}
echo "TCP服务器已启动,监听 0.0.0.0:8080\n";
// 设置非阻塞模式
stream_set_blocking($server, false);
// 存储所有客户端连接
$clients = [$server];
while (true) {
$read = $clients;
$write = null;
$except = null;
// 使用select监听连接
if (stream_select($read, $write, $except, 0, 10000) > 0) {
// 新连接
if (in_array($server, $read)) {
$client = stream_socket_accept($server);
if ($client) {
stream_set_blocking($client, false);
$clients[] = $client;
echo "新客户端连接: " . stream_socket_get_name($client, true) . "\n";
}
// 移除服务器对象,避免重复处理
$key = array_search($server, $read);
unset($read[$key]);
}
// 处理客户端数据
foreach ($read as $client) {
$data = fread($client, 8192);
if ($data === false || $data === '') {
// 客户端断开
echo "客户端断开连接\n";
fclose($client);
$key = array_search($client, $clients);
unset($clients[$key]);
} else {
// 处理接收到的数据
echo "收到数据: " . trim($data) . "\n";
// 发送响应
fwrite($client, "服务器收到: " . $data);
// 如果收到exit命令,关闭连接
if (trim($data) === "exit") {
fclose($client);
$key = array_search($client, $clients);
unset($clients[$key]);
}
}
}
}
}
使用 pcntl 多进程方案
适合需要高并发的场景:
<?php
// 创建服务器
$server = stream_socket_server(
"tcp://0.0.0.0:8080",
$errno,
$errstr
);
if (!$server) {
die("无法创建服务器: $errstr ($errno)");
}
// fork 5个子进程
$workers = 5;
for ($i = 0; $i < $workers; $i++) {
$pid = pcntl_fork();
if ($pid == -1) {
die("无法创建子进程");
} elseif ($pid) {
// 父进程继续
continue;
} else {
// 子进程处理连接
while (true) {
$client = @stream_socket_accept($server);
if ($client) {
// 处理客户端请求
$pid = posix_getpid();
echo "进程 $pid 处理新连接\n";
// 读取数据
$request = fread($client, 8192);
echo "收到: " . $request . "\n";
// 发送响应
$response = "处理完成 (进程 $pid): " . $request;
fwrite($client, $response);
fclose($client);
}
usleep(100);
}
}
}
// 父进程等待子进程
while (true) {
$status = 0;
$pid = pcntl_wait($status);
echo "子进程 $pid 退出\n";
}
使用 Swoole 扩展(推荐)
Swoole是PHP最完善的TCP服务器解决方案:
<?php
// 创建Swoole TCP服务器
$server = new Swoole\Server('0.0.0.0', 8080);
// 设置运行参数
$server->set([
'worker_num' => 4, // worker进程数
'backlog' => 128, // 监听队列长度
'max_connection' => 10000, // 最大连接数
'daemonize' => false, // 是否守护进程化
]);
// 监听连接建立事件
$server->on('Connect', function ($server, $fd) {
echo "客户端连接: fd=$fd\n";
});
// 监听数据接收事件
$server->on('Receive', function ($server, $fd, $reactor_id, $data) {
echo "收到数据 fd=$fd: " . $data . "\n";
// 发送响应
$server->send($fd, "服务器收到: " . $data . "\n");
});
// 监听连接关闭事件
$server->on('Close', function ($server, $fd) {
echo "客户端断开: fd=$fd\n";
});
// 服务器启动
$server->start();
完整的客户端测试代码
<?php
// TCP客户端测试代码
$client = stream_socket_client(
"tcp://127.0.0.1:8080",
$errno,
$errstr,
30
);
if (!$client) {
echo "连接失败: $errstr ($errno)\n";
exit;
}
echo "连接成功,发送数据...\n";
// 发送数据
fwrite($client, "你好,服务器!");
// 读取响应
$response = fread($client, 8192);
echo "服务器响应: " . $response . "\n";
// 关闭连接
fclose($client);
使用 Workerman(另一个常见方案)
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Workerman\Worker;
// 创建TCP服务
$tcp_worker = new Worker("tcp://0.0.0.0:8080");
// 设置进程数
$tcp_worker->count = 4;
// 当客户端连接时触发
$tcp_worker->onConnect = function($connection) {
echo "新连接\n";
};
// 当收到数据时触发
$tcp_worker->onMessage = function($connection, $data) {
$connection->send("收到: " . $data);
};
// 当连接关闭时触发
$tcp_worker->onClose = function($connection) {
echo "连接关闭\n";
};
// 启动服务
Worker::runAll();
性能对比
| 方案 | 并发能力 | 开发复杂度 | 扩展性 | 适用场景 |
|---|---|---|---|---|
| stream_socket | 低 | 简单 | 差 | 学习/小规模 |
| pcntl多进程 | 中 | 中等 | 一般 | 中等规模 |
| Swoole | 高 | 中等 | 好 | 生产环境 |
| Workerman | 高 | 简单 | 好 | 生产环境 |
安装建议
对于生产环境,推荐使用Swoole:
# 安装Swoole pecl install swoole # 或使用Docker docker run -p 8080:8080 -v $(pwd):/app php:8.2-cli \ sh -c "docker-php-ext-install swoole && php /app/server.php"
注意事项
- 超时处理:设置合理的超时时间
- 错误处理:完善异常和错误处理机制
- 资源管理:及时释放连接和资源
- 安全防护:防止恶意攻击和资源耗尽
- 日志记录:记录重要操作和错误信息
选择哪种方案取决于你的具体需求,生产环境推荐使用Swoole或Workerman。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播