You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP监听端口接收设备数据并写入MySQL数据库的技术问询

搞定PHP监听端口接收设备数据并写入MySQL的方案

我来帮你完善这个需求——你提到设备(192.168.1.113)会往192.168.1.100的8996端口发数据,想用PHP监听接收并写入MySQL,先给你把没写完的监听脚本补全,再整合数据库写入的逻辑。

一、先搞定端口监听(验证数据接收)

首先要注意:浏览器访问的方式不适合做持续监听,因为PHP的CLI命令行模式才是做长期运行服务的正确姿势——浏览器请求有超时限制,没法一直挂着等数据。下面是完整的TCP监听脚本:

<?php
error_reporting(E_ALL);
set_time_limit(0); // 取消脚本超时限制
ob_implicit_flush(); // 让输出自动刷新,不用手动flush

$listen_ip = '192.168.1.100';
$listen_port = 8996;
$max_connections = 10;

// 创建TCP Socket
if (!($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) {
    $error_code = socket_last_error();
    $error_msg = socket_strerror($error_code);
    die("创建Socket失败:[$error_code] $error_msg\n");
}

// 设置端口复用,避免重启脚本时提示端口被占用
if (!socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1)) {
    $error_code = socket_last_error();
    $error_msg = socket_strerror($error_code);
    die("设置Socket选项失败:[$error_code] $error_msg\n");
}

// 绑定监听地址和端口
if (!socket_bind($sock, $listen_ip, $listen_port)) {
    $error_code = socket_last_error();
    $error_msg = socket_strerror($error_code);
    die("绑定Socket失败:[$error_code] $error_msg\n");
}

// 开始监听端口
if (!socket_listen($sock, $max_connections)) {
    $error_code = socket_last_error();
    $error_msg = socket_strerror($error_code);
    die("监听Socket失败:[$error_code] $error_msg\n");
}

echo "等待设备连接中... 监听地址:$listen_ip:$listen_port\n";

// 循环处理客户端连接
while (true) {
    // 接受设备的连接请求
    if (($client_sock = socket_accept($sock)) === false) {
        $error_code = socket_last_error();
        $error_msg = socket_strerror($error_code);
        echo "接受连接失败:[$error_code] $error_msg\n";
        continue;
    }

    // 获取连接设备的IP地址
    socket_getpeername($client_sock, $device_ip);
    echo "新设备连接:$device_ip\n";

    // 读取设备发送的数据(每次读1024字节,可根据实际数据大小调整)
    $received_data = socket_read($client_sock, 1024);
    if (!$received_data) {
        echo "设备未发送数据,断开连接\n";
        socket_close($client_sock);
        continue;
    }

    // 输出接收到的数据,验证是否能正常接收
    $clean_data = trim($received_data);
    echo "收到来自 $device_ip 的数据:$clean_data\n";

    // --- 这里后续会加写入MySQL的逻辑 ---

    // 可选:给设备回复确认信息(如果设备需要收到确认才继续发送)
    socket_write($client_sock, "数据已接收\n", strlen("数据已接收\n"));

    // 关闭当前设备的连接
    socket_close($client_sock);
}

// 关闭监听Socket(循环不会走到这里,除非手动终止脚本)
socket_close($sock);
?>

运行方式:

  1. 把代码存成port_listener.php
  2. 打开服务器的命令行,运行:php port_listener.php
  3. 确保服务器的8996端口没被占用,防火墙允许该端口的TCP入站连接

二、整合MySQL写入逻辑

当你确认能正常收到数据后,就可以把数据写入数据库了。下面是整合后的完整脚本,记得替换成你自己的数据库信息:

<?php
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();

// --- MySQL配置 ---
$db_host = 'localhost'; // 数据库地址,一般是localhost
$db_user = 'your_db_user'; // 数据库用户名
$db_pass = 'your_db_password'; // 数据库密码
$db_name = 'your_db_name'; // 数据库名
$table_name = 'device_data'; // 存储数据的表名

// 连接MySQL
$db_conn = mysqli_connect($db_host, $db_user, $db_pass, $db_name);
if (!$db_conn) {
    die("数据库连接失败:" . mysqli_connect_error() . "\n");
}
echo "数据库连接成功\n";

// --- 端口监听配置 ---
$listen_ip = '192.168.1.100';
$listen_port = 8996;
$max_connections = 10;

// 创建Socket并监听(和之前的代码一致)
if (!($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) {
    $error_code = socket_last_error();
    $error_msg = socket_strerror($error_code);
    die("创建Socket失败:[$error_code] $error_msg\n");
}

if (!socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1)) {
    $error_code = socket_last_error();
    $error_msg = socket_strerror($error_code);
    die("设置Socket选项失败:[$error_code] $error_msg\n");
}

if (!socket_bind($sock, $listen_ip, $listen_port)) {
    $error_code = socket_last_error();
    $error_msg = socket_strerror($error_code);
    die("绑定Socket失败:[$error_code] $error_msg\n");
}

if (!socket_listen($sock, $max_connections)) {
    $error_code = socket_last_error();
    $error_msg = socket_strerror($error_code);
    die("监听Socket失败:[$error_code] $error_msg\n");
}

echo "等待设备连接中... 监听地址:$listen_ip:$listen_port\n";

while (true) {
    if (($client_sock = socket_accept($sock)) === false) {
        $error_code = socket_last_error();
        $error_msg = socket_strerror($error_code);
        echo "接受连接失败:[$error_code] $error_msg\n";
        continue;
    }

    socket_getpeername($client_sock, $device_ip);
    echo "新设备连接:$device_ip\n";

    $received_data = socket_read($client_sock, 1024);
    if (!$received_data) {
        echo "设备未发送数据,断开连接\n";
        socket_close($client_sock);
        continue;
    }

    $clean_data = trim($received_data);
    echo "收到来自 $device_ip 的数据:$clean_data\n";

    // --- 写入MySQL的逻辑 ---
    if (!empty($clean_data)) {
        // 用预处理语句防止SQL注入,这是最安全的方式
        $stmt = mysqli_prepare($db_conn, "INSERT INTO $table_name (device_ip, received_data, receive_time) VALUES (?, ?, NOW())");
        mysqli_stmt_bind_param($stmt, "ss", $device_ip, $clean_data);
        
        if (mysqli_stmt_execute($stmt)) {
            echo "数据成功写入数据库\n";
        } else {
            echo "写入数据库失败:" . mysqli_stmt_error($stmt) . "\n";
        }
        mysqli_stmt_close($stmt);
    }

    socket_write($client_sock, "数据已接收\n", strlen("数据已接收\n"));
    socket_close($client_sock);
}

mysqli_close($db_conn);
socket_close($sock);
?>

数据库表结构参考:

你需要先创建对应的表,比如:

CREATE TABLE device_data (
    id INT AUTO_INCREMENT PRIMARY KEY,
    device_ip VARCHAR(45) NOT NULL,
    received_data TEXT NOT NULL,
    receive_time DATETIME NOT NULL
);

三、常见问题排查

  • 收不到数据:先检查服务器防火墙是否开放8996端口,再用telnet 192.168.1.100 8996测试端口是否能连通,或者用抓包工具确认设备是否真的在发数据
  • 脚本运行一段时间后停止:用nohup php port_listener.php &让脚本在后台运行,这样关闭终端也不会停止;或者用Supervisor这类进程管理工具,保证脚本意外退出后自动重启
  • 数据乱码:确认设备发送的编码、PHP脚本编码、数据库表编码一致,推荐统一用UTF-8

内容的提问来源于stack exchange,提问作者nitro23456

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:29:50