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); ?>
运行方式:
- 把代码存成
port_listener.php - 打开服务器的命令行,运行:
php port_listener.php - 确保服务器的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
相关产品推荐
相关产品推荐

