通过 SNMP 协议监控 HP 打印机的物理打印完成状态,而不是仅依赖打印队列的任务提交。
job.print() 阻塞,等待任务进入打印队列baseCountbaseCount + 1 时,触发回调HP 3004dn 需要开启 SNMP 支持(出厂默认开启):
网络 → SNMP启用 SNMP v1/v2c 已勾选团体名称(读取) 为 public(默认值)UDP 端口 为 161(默认值)编辑 config/print.properties:
printer.type=hp
printer.name=HP LaserJet 3004
# 添加打印机 IP(替换为实际 IP)
printer.ip=192.168.1.100
确保客户端能访问打印机的 UDP 161 端口:
# Windows 测试连通性
ping 192.168.1.100
# 如果有防火墙,需放行 UDP 161 端口
# 在 mes-print 项目目录
cd C:/Users/jcxa/Desktop/T09/khd/mes-print
# 编译测试程序
javac -encoding UTF-8 -d build/classes -cp "lib/*" src/com/mes/print/TestSnmp.java
# 运行测试(替换为实际打印机 IP)
java -cp "build/classes;lib/*" com.mes.print.TestSnmp 192.168.1.100
预期输出:
=== SNMP 打印机监控测试 ===
打印机 IP: 192.168.1.100
1. 测试连接...
[PrinterMonitor] 已连接到打印机:192.168.1.100
[PrinterMonitor] 测试连接 - 页数=1234, 状态=3
2. 查询打印机状态...
总打印页数: 1234
打印机状态: 3 (3=空闲, 4=打印中, 5=预热)
3. 开始监控打印完成(请手动发送打印任务)...
按 Ctrl+C 退出监控
然后手动打印一张测试页,程序会检测到页数变化并输出:
[PrinterMonitor] 当前页数=1234,目标=1235
[PrinterMonitor] 当前页数=1235,目标=1235
[PrinterMonitor] 打印完成检测到!页数从 1234 → 1235
✓ 检测到打印完成!
错误:连接失败,请检查...
排查:
尝试用 Windows 自带工具测试: ```bash
# 测试查询 snmpget -v2c -c public 192.168.1.100 1.3.6.1.2.1.43.10.2.1.4.1.1
### 2. 页数不变化
**现象**:打印了但页数计数器不增加
**原因**:
- 某些打印机型号的 OID 不同
- 打印任务被取消或失败
**解决**:
- 尝试其他 OID(参考打印机 MIB 文档)
- 检查打印机实际是否出纸
### 3. 监控超时
**现象**:60 秒后仍未检测到完成
**原因**:
- 打印任务卡在队列(打印机离线/缺纸/卡纸)
- 大文件打印耗时超过 60 秒
**解决**:
- 增加超时时间(修改 `HpPrinter.java:90` 的 60 改为更大值)
- 检查打印机物理状态
## 性能影响
- **轮询间隔**:2 秒/次
- **网络开销**:每次查询 ~200 字节
- **CPU 占用**:极低(单独线程,非阻塞)
- **延迟**:物理打印完成后 0-2 秒内检测到
## 禁用 SNMP 监控
如果不需要物理打印完成检测,只需注释掉配置:
```properties
# printer.ip=192.168.1.100
此时打印任务提交到队列后立即返回(原有行为)。
// 创建监控器
PrinterMonitor monitor = new PrinterMonitor("192.168.1.100");
monitor.init();
// 查询页数
Long count = monitor.getPageCount();
// 查询状态
Integer status = monitor.getPrinterStatus();
// 1=其他, 3=空闲, 4=打印中, 5=预热
// 监控打印完成
monitor.waitForPrintComplete(
1, // 预期页数增量
() -> { // 完成回调
System.out.println("打印完成");
},
60 // 超时秒数
);
// 关闭监控
monitor.close();
HpPrinter printer = new HpPrinter();
// 启用 SNMP 监控
printer.enableSnmpMonitor("192.168.1.100");
// 设置完成回调
printer.setOnPrintComplete(() -> {
System.out.println("物理打印完成");
});
// 打印(会阻塞直到物理打印完成)
printer.printFlowCard(data);
理论上支持所有实现了 Printer MIB (RFC 3805) 的网络打印机,包括:
不支持: