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

PHP TCP Socket无法读取PLC 502端口数据求助

PHP TCP Socket无法读取PLC Modbus TCP(502端口)数据的问题排查与修复

问题代码中的核心错误

  • 角色混淆:PLC在502端口提供Modbus TCP服务,你的PHP程序应作为客户端发起连接,但代码错误使用了socket_bind()(服务端绑定端口的操作),而非socket_connect()。
  • 函数误用:socket_recvfrom()是UDP通信的函数,TCP场景下应使用socket_read()或socket_recv()。
  • 缺少协议请求:Modbus TCP是请求-响应模式,必须先发送符合规范的请求报文,PLC才会返回数据,直接等待接收无意义。

修正后的代码示例(以读取保持寄存器为例)

<?php
$plcAddress = "10.22.100.210";
$plcPort = 502;

// 创建TCP socket
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("无法创建Socket: " . socket_strerror(socket_last_error()) . "\n");

// 连接PLC
$result = socket_connect($socket, $plcAddress, $plcPort) or die("无法连接PLC: " . socket_strerror(socket_last_error()) . "\n");

// 构造Modbus TCP请求报文(示例:读取起始地址0的1个保持寄存器)
// 格式:事务处理标识(2字节)+协议标识(2字节)+长度(2字节)+单元标识(1字节)+功能码(1字节)+起始地址(2字节)+寄存器数量(2字节)
$request = pack('nnnCnn', 0x0001, 0x0000, 0x0006, 0x01, 0x03, 0x0000, 0x0001);

// 发送请求
socket_write($socket, $request, strlen($request)) or die("发送请求失败: " . socket_strerror(socket_last_error()) . "\n");

// 读取响应(Modbus响应最小长度是9字节)
$response = socket_read($socket, 1024) or die("读取响应失败: " . socket_strerror(socket_last_error()) . "\n");

// 解析响应(转换为十六进制便于查看)
echo "PLC响应数据(十六进制): " . bin2hex($response) . "\n";

// 关闭socket
socket_close($socket);
?>

额外注意事项

  • 确保PHP的sockets扩展已启用(可通过phpinfo()查看)。
  • 检查PHP运行环境的防火墙是否允许访问PLC的502端口。
  • 不同PLC的Modbus参数(如单元标识、寄存器地址)可能不同,需根据PLC手册调整请求报文。

内容的提问来源于stack exchange,提问作者tamer aktı

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 17:09:54