Linux下Java如何访问PLC服务创建的命名管道?
解决方法
一、不要选择/proc下的匿名管道
你在/proc/428576/fd里看到的pipe:[xxxx]是匿名管道,这类管道是进程内部或父子进程间的私有通信通道,外部进程无法直接访问,所以不能用这些管道来和PLC服务端通信。
二、找到S7NetPlus创建的命名管道实际路径
在Linux系统中,.NET的NamedPipeServerStream(S7NetPlus底层依赖该组件创建命名管道)会将命名管道文件放在如下路径:
- 通常是
/tmp/named_pipes/<你的用户名>/<管道名> - 部分.NET版本可能放在
/tmp/.dotnet/NamedPipes/<管道名>
你可以通过以下方式快速定位:
- 确认PLC服务端代码中定义的管道名称(比如你Windows测试代码里的
pipename) - 用
find命令全局查找对应管道文件:
sudo find /tmp -name "pipename"
- 或者用
lsof命令查看服务端进程关联的命名管道:
sudo lsof -p 428576 | grep -E "(FIFO|pipe)"
(输出里带具体文件路径的就是命名管道,匿名管道只会显示pipe:[inode]格式)
三、Java中写入Linux命名管道的代码
找到正确的管道路径后,直接用Java的文件流操作即可,和操作普通文件逻辑一致:
// 替换成实际的命名管道路径,比如/tmp/named_pipes/userjo/pipename String pipePath = "/tmp/named_pipes/userjo/pipename"; try (FileOutputStream fos = new FileOutputStream(pipePath)) { byte val = 1; fos.write(val); fos.flush(); // 确保数据写入管道 } catch (IOException e) { e.printStackTrace(); }
也可以使用RandomAccessFile实现:
String pipePath = "/tmp/named_pipes/userjo/pipename"; try (RandomAccessFile pipe = new RandomAccessFile(pipePath, "rw")) { byte val = 1; pipe.write(val); } catch (IOException e) { e.printStackTrace(); }
注意:Linux命名管道是阻塞式的,写入操作会在没有读端(服务端未打开管道)时卡住,确保PLC服务端已经启动并监听目标管道。
内容的提问来源于stack exchange,提问作者Hrvoje
相关产品推荐
相关产品推荐

