ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

IPP网络打印协议解析:从驱动less打印到ipptool调试与配置实战

IPP网络打印协议解析:从驱动less打印到ipptool调试与配置实战 简介这是一份面向网络开发者的 IPP 网络打印协议源码包完整呈现基于 HTTP/1.1 的打印作业提交、打印机状态查询、作业控制及属性扩展等标准实现强调跨平台设备间的互操作性适合需要开发打印客户端、研究协议解析或进行系统集成的人员参考。包内共 32 个文件以 C 语言源文件.c/.h为主体配合 Makefile 与 format 配置文件构成可构建的协议框架另含 svn-base 版本元数据与 README 说明整体仅 35KB结构紧凑便于快速阅读。当前已有 3860 人学习下载源码重点覆盖请求/响应解析、状态机流转、IPP 数据编码、错误处理以及基于 HTTPS 的安全通信等模块读者可从底层报文开始理解协议工作流程。对于希望自定义打印方案或排查跨平台打印问题的开发者这份代码提供了可直接研读的实例与扩展基础。1. IPP网络打印协议为什么现在驱动less打印都在喊它打印机驱动装不上设备明明连着局域网系统里却只给你一堆 LPR 或 Raw Queue 端口——这是做网络打印集成最常见的开局。IPP网络打印协议Internet Printing Protocol就是为了结束这种黑匣子状态它把打印动作变成基于 HTTP 的标准请求作业提交、状态查询、能力协商都能用明文请求和响应去验证。它能解决的是驱动缺失、跨平台支持、移动端免驱打印这类问题适合设备集成、运维工程师以及准备在自研系统里接入打印能力的人。接下来我不背协议编号而是把 IPP 当服务去拆先认属性再用手头工具摸清设备最后配进打印服务组件并处理那些翻车点。2. 先看懂IPP它与LPR/SMB的差别和你要记住的三个属性在动手敲命令前我得先把一个常见误解纠正过来IPP 不是像 LPR 那样“提交完就进队列、状态全靠猜”它是一套自带属性查询的 RPC 式协议。新手最容易把 IPP 和打印驱动混在一起实际上 IPP 关心的不是光栅怎么拼而是“能不能打、打成什么样、当前什么状态”。下面从协议骨架说起顺便把选型逻辑讲清楚。2.1 IPP是“带属性的HTTP”端口631、二进制请求、operationIPP 的传输层是 HTTP/1.1默认端口 631数据体是二进制编码的请求和响应。它把一次打印动作包装成一个 operation request打印机或者打印服务器处理后返回 operation response。客户端不只提交作业还可以先问能力。这与 LPR/SMB 的差别很大LPR 只有简单的控制文件和数据文件没有标准的状态码集合SMB 打印即便能共享队列对网络发现、TLS 和跨平台属性表达都很吃力。一次 IPP 调用的目标叫 Printer URI形如ipp://192.168.1.50/ipp/print。客户端 POST 一个二进制请求到这个 URI请求里必须有 Operation ID 和 Request ID。常见的 operation 如下表后面所有调试都绕不开这几个。Operation数值作用Print-Job0x0002提交打印作业文件内容放在请求体内Validate-Job0x0004只验证作业可不可打印不真正提交Get-Printer-Attributes0x000B获取打印机的能力与当前状态Get-Jobs0x000A查询排队中的作业列表Cancel-Job0x0008取消指定作业如果你习惯的是 JSON 接口第一次看 IPP 会觉得它像黑匣子因为不是文本。你无法用 curl 直接看懂响应必须用专门的ipptool或者抓包看 631 端口。这也是为什么第 3 章全部以ipptool为主它能帮你把 IPP 的二进制信封拆开让你看到属性名和值。选型层面现代驱动less打印之所以都选 IPP就是因为它把“查询能力”和“提交作业”放进同一个协议而不是像 LPR 那样只能单向投递。2.2 属性树Printer / Job / Document 三层别把三者搞混属性是 IPP 的“参数数据库”。客户端和服务端交互时所有条件、能力、状态都用名为“属性”的键值对表达。值类型有很多keyword、boolean、integer、enum、resolution、rangeOfInteger 等每个属性属于一个“属性组”在二进制报文里以 tag 区分比如 operation-attributes-tag、printer-attributes-tag、job-attributes-tag。打印机端最重要的三层对象是 Printer、Job、Document。Printer 对象描述这台设备能干什么printer-name、printer-stateidle/processing/stopped、printer-is-accepting-jobs、printer-up-time、document-format-supported都是这一层。Job 对象是你提交一次打印后产生的工作单job-id、job-state、job-state-reasons能告诉你作业是被处理、暂停还是卡纸。Document 对象描述文档本身的属性像document-format、document-natural-language很多场景下它不仅依附在 Job 上在提交请求里还要单独用属性组声明。理解这个分层有助于排错例如你提交作业后打印机没有任何反应应先查 Printer 层的printer-is-accepting-jobs与 Job 层的job-state-reasons而不是先去重装驱动。后面第 5 章就会遇到这类问题。另外请求能力时用requested-attributes指定你想要的属性名列表这个参数经常被写错所以单独强调一下它写在操作属性组里值是 keyword 类型可以用all也可以传多个属性名。2.3 ipp:// 与 ipps://URI结构、端口与“你看到的631未必是IPP”URI 是 IPP 的地址入口。标准格式是ipp://[用户]主机[:端口]/路径带 TLS 时写ipps://默认端口同样习惯用 631不是常见的 443。路径常见的是/ipp/print、/ipp、/printers/xxx厂商可以自行注册路径所以碰到具体设备时不要想当然。这里最容易踩坑一台打印机的 631 端口上可能同时站着 HTTP 管理服务和 IPP 服务根路径是 HTML/ipp/print才是 IPP 端点。你用curl http://host:631/能得到 HTML不代表设备支持 IPP只能说明它开了 HTTP。正确的探测方式是用ipptool或设备广播出来的服务发现结果不是浏览器。这个习惯能省掉后面一半时间。加密方面ipps://在同一个 URI 上用 TLS 封装 IPP证书常常是出厂自签名第一次连接时打印服务组件会因为“证书未信任”把打印机标记为认证失败这又是另一个独立的坑。所以把“端口 631”和“协议是 IPP”分开记忆比硬记端口安全得多。这一章最后补一个选型结论LPR 和 SMB 也不是不能用但在“无驱动”“跨平台”“作业状态可查”这三个需求面前都要打折扣。IPP 的请求-响应模型让客户端可以先问能力再提交作业这正是当前移动端免驱打印方案的核心机制。所以标题里说的 IPP 网络打印协议不是一个需要背的 RFC 编号而是一套能直接拿来测、拿来配、拿来写网关的和 HTTP 同源的协议。3. 用ipptool在本地把一台IPP打印机摸清楚ipptool是能直接和打印机对话的命令行工具在多数带打印服务的 Linux 发行版和桌面系统上都可以直接用它。它的好处是帮你把二进制请求封装好你只要写一个“测试文件”描述要发什么 operation、带哪些属性即可。下面三步是从“确认支持”到“提交真实作业”的最小路径。3.1 确认设备支持IPP的最小命令一条ipptool加heredocipptool -tv ipp://192.168.1.50:631/ipp/print EOF { OPERATION Get-Printer-Attributes GROUP operation-attributes-tag ATTR charset attributes-charset utf-8 ATTR naturalLanguage attributes-natural-language en ATTR uri printer-uri $uri } EOF这里的-tv表示 verbose 输出工具会把响应的操作状态码和属性值都打印出来$uri是 ipptool 自动把命令行传入的 Printer URI 当作printer-uri属性值所以你不用再重复写 IP。请求里的 operation-attributes-tag 是必须的头部属性组attributes-charset、attributes-natural-language是 IPP 的两个通用属性每次都要带。如果设备返回successful-ok说明它确实支持 IPP如果返回client-error-not-found多半是路径不对换/ipp或去设备 Web 管理端查真实路径。这一条命令验证的事情比翻说明书有价值它直接证明设备在 631 端口上响应 IPP 请求。后续所有配置都以这条命令返回successful-ok为前提。如果失败先不要怪驱动第一步就要怀疑 URI 路径、端口、防火墙三层。3.2 让打印机自己“报”能力requested-attributes 与 document-format-supported一旦确认能通接下来就要问打印机到底支持什么。很多同事在配置网络打印时喜欢先在驱动列表里找型号其实 IPP 的正确姿势是让打印机自己告诉你它能吃哪些 document-format。下面请求只拉三个关键属性。ipptool -tv ipp://192.168.1.50:631/ipp/print EOF { OPERATION Get-Printer-Attributes GROUP operation-attributes-tag ATTR charset attributes-charset utf-8 ATTR naturalLanguage attributes-natural-language en ATTR uri printer-uri $uri ATTR keyword requested-attributes printer-state ATTR keyword requested-attributes printer-is-accepting-jobs ATTR keyword requested-attributes document-format-supported } EOFrequested-attributes可以重复声明每个属性名是 keyword 类型。常见的响应里printer-state是数字枚举3 表示 idle4 表示 processing5 表示 stoppedprinter-is-accepting-jobs是 booleandocument-format-supported会列出类似application/pdf、image/pwg-raster、image/jpeg这样的 MIME 类型。这就是之后提交作业要用的依据打印机声明支持什么我们就提什么而不是想当然发 PDF 或 PS。有一个常见误用以为支持application/pdf就代表支持高分辨率 / 光栅格式这完全两回事。有些设备 PDF 解析能力有限但image/pwg-raster是它的原生格式有些兼容设备反而对 PWG 支持不完整。所以在接入新设备时我一般会把document-format-supported完整列表存下来当作后续提交参数的“白名单”。这一步做扎实后面作业被拒的概率会低很多。3.3 提交一个真实作业Print-Job、document-format 与 FILE/DATA 的区别验证能力之后就到了真正提交作业的环节。用Print-Job并带上一个本地文件是最直接的端到端测试。ipptool -tv ipp://192.168.1.50:631/ipp/print EOF { OPERATION Print-Job GROUP operation-attributes-tag ATTR charset attributes-charset utf-8 ATTR naturalLanguage attributes-natural-language en ATTR uri printer-uri $uri GROUP job-attributes-tag ATTR mimeMediaType document-format application/pdf ATTR name job-name test-ipp-job FILE /tmp/test.pdf } EOFFILE /tmp/test.pdf会把文件内容作为请求体发给打印机和 HTTP POST 的 body 概念一样。document-format必须放在 job-attributes-tag 属性组里告诉打印机这份数据是什么格式。如果打印机不认这个格式响应里会出现client-error-document-format-not-supported如果提交成功响应里会带job-id和job-uri这两个值需要记下来后面查询和取消作业都用得上。FILE和DATA的区别是FILE引用磁盘上的二进制文件适合 PDF、PWG 光栅DATA直接把后面的字符串当作文档内容适合快速测试纯文本。测试纯文本输出时把document-format改成text/plain然后写DATA hello world就可以。提交之后如果想确认作业是否真的进入队列再补一个 Get-Jobs看返回的job-id是否在列表里。这样一个完整的 IPP 客户端验证流程就闭环了。4. 在打印服务组件里接一个IPP打印机URI、驱动与端口的参数怎么设上一章证明了设备能通接下来要把它纳入系统打印服务。这里以最常见的打印服务组件命令行工具为例。配置的关键点不是“选驱动”而是“URI 对不对”和“用什么模式让它自动取能力”。4.1 用 lpadmin 配置 IPP 打印机的最小命令lpadmin -p office-printer -E -v ipp://192.168.1.50:631/ipp/print -m everywhere lpstat -p office-printer lpoptions -p office-printer -o mediaiso_a4_210x297mm第一条命令里-p office-printer是给本机起的队列名-E表示同时启用该队列-v指定设备 URI-m everywhere表示使用驱动less模式不指定厂商 PPD而是让打印服务组件启动时去打印机上动态抓取能力。之后用lpstat -p office-printer查看队列状态如果显示idle并且没有disabled说明队列已经可用lpoptions设置默认纸张为 A4这一步在跨区域使用设备时特别重要。-m everywhere是目前最推荐的做法前提是设备支持 IPP Everywhere。换句话说第 3 章看到的document-format-supported就是它后续协商的基础服务组件会直接生成一个临时 PPD这个 PPD 里写着设备支持的纸型、解析度、色彩能力而不是从厂商安装盘里找。如果设备不支持动态能力发现-m everywhere可能会失败此时退回到-m raw可以先把队列建起来但 raw 模式下系统不控制页面尺寸和格式只把数据直接透传给打印机。所以raw只适合应急不能当长期方案。4.2 driverless: URI 与 IPP Everywhere从自动发现到接入在打印服务组件的语境里driverless是能力和 PPD 之间的桥梁。你不需要自己找驱动只要确认设备支持 IPP系统就能通过Get-Printer-Attributes拿到media-supported、resolution-supported、print-color-mode-supported再把这些属性翻译成打印选项。这也是为什么很多人配好的ipp://队列在安装界面里看不到厂家驱动但打出来的效果反而比老驱动正常。接入时还要注意 URI 的路径差异。同样是支持 IPP 的设备有的路径是/ipp/print有的是/ipp/printers/myprinter有的只在ipps://上开放。我一般会在配置前先执行一次lpinfo -v | grep -i ipp让打印服务组件扫描局域网网络服务看它发现的实际 URI。这个命令会列出类似ipp://192.168.1.50:631/ipp/print的地址比手填更可靠。手动填写时最怕把厂商 Web 管理页的地址当成打印机 URI那样队列会一直处于“无法连接”状态。如果你接的是带加密的ipps://第一件事不是想着关 TLS而是把打印机的根证书导入系统信任库。自签名证书的常见问题会在第 5 章展开这里先记住IPP over TLS 的默认端口仍然可能是 631不要一见 443 就以为肯定是 IPPS也不要把 80 端口的 Web 管理页当成 IPP。4.3 移动端和AirPrint的落地原来是同一套移动端免驱打印能“自动发现打印机、不用装驱动”是因为手机系统在局域网里通过 DNS-SD 找到了_ipp._tcp服务拿到 Printer URI 后用和ipptool一样的 IPP 请求去拿打印机能力再把文档转成打印机接受的光栅格式提交。也就是说你在服务组件里配好的ipp://队列天然可以被移动端发现前提是这台机器开启了服务发现广播。对做设备集成的工程师来说这里有一个值得记下来的点如果自研设备想让手机直接打印不需要去适配各家私有协议只需要对外暴露一个符合 IPP 的端点比如/ipp/print同时广播_ipp._tcp服务即可。设备端要自己实现至少Get-Printer-Attributes和Print-Job两个操作返回document-format-supported时列出的格式就是移动端会尝试使用的格式。如果它发现支持image/pwg-raster就会把页面渲染成该格式再打。所以前面那些ipptool命令不是玩具它们与手机实际的握手流程基本相同。唯一区别是手机更多用服务发现自动填充 URI而手工配置时 URI 要靠人填。理解这一点后你在排手机打印失灵的问题时思路会从“是不是系统问题”变成“这个端点的 IPP 请求到底返回了什么”排查维度完全不同。5. IPP调试与避坑我踩过的5个常见问题这一章完全是一线踩坑的记录。IPP 本身不算复杂但因为它和 HTTP、端口、Web 管理页、加密这些东西混在一起配置时总会有几个“怎么想都不对”的时刻。以下五条按从网络到应用的顺序写每条都是真实翻过车的。5.1 端口631连不上但打印机明明通着现象用nc -vz 192.168.1.50 631测试超时但打印机面板能进厂商 Web 管理端也能打开。原因这台设备的 IPP 服务不在 631 端口或者 631 端口被安全策略关掉了只保留 Web 管理端口。解决不要硬猜优先用设备广播的服务发现结果。可以在设备 Web 管理端里找“网络打印 / IPP / 协议设置”这类入口把 IPP 打印服务打开记下它提示的 URL。我遇到过一个型号它的 IPP 端点端口是 8080路径是/ipp/print而 631 留给了一个早就淘汰的 LPR 服务。后来靠设备说明书里的打印服务器配置页才找到真实 URI。所以第 2 章强调“端口 631 不等于 IPP”这里是血泪印证。碰到nc不通第一反应不该是“不支持 IPP”而是“我们猜的端口和路径不对”。5.2 作业已接受但打印机长时间不打印现象ipptool返回successful-ok响应里也有job-id但打印机面板上一直没有作业。原因设备把作业放进了 Hold 队列等待面板确认或者 PDF 格式被接收但 RIP 解析失败作业停在 pending / held 状态。解决提交完成后立刻用Get-Jobs或Get-Job-Attributes查job-state-reasons这个属性会告诉你为什么停着。常见值里job-hold-until-specified表示设备被设置成“先暂存再打印”compression-error表示数据解压失败document-format-error表示格式内容损坏。看到 held 后去设备面板上释放作业或者通过Set-Job-Attributes把job-hold-until改成no-hold。不要因为第一发没出来就反复提交否则队列会被撑满最后连状态查询都变慢。5.3 用curl查631端口看到HTML误以为设备支持IPP现象curl http://192.168.1.50:631/返回一个 HTML 管理页于是判断“这家打印机走 IPP”配置后队列却一直报无法连接。原因631 端口上同时有 HTTP 管理服务浏览器访问根路径拿到的是 HTML 页面IPP 的二进制请求必须 POST 到具体路径比如/ipp/print而且请求体不是普通表单。解决用ipptool而不是 curl 去验证。curl 能拿到 HTML 只能说明该端口有 HTTP 服务不能说明它是 IPP。这个误区之所以常见是因为很多打印服务器把自己的状态页也放在 631 上根路径和 IPP 端点共存。正确习惯是写一个小测试文件用ipptool -tv ipp://host/ipp/print getattrs.test跑一次看返回状态。如果路径不对就把/ipp/print换成/ipp再看。翻车几次后你会发现路径调试比端口调试花的时间多得多。5.4 认证/TLS导致无论是ipptool还是打印服务组件都无法协商现象ipptool请求返回client-error-not-authenticated或者日志里出现 SSL/TLS 握手失败同一个 URI 换了网络环境又好了。原因打印机只允许认证用户访问 IPP或者只开放ipps://并要求 TLS且证书不受本机信任。解决优先改用ipps://把打印机根证书导入系统信任库如果只是临时测试且设备允许关闭加密可以明确配置成局域网ipp://但不要在生产环境关掉。这里要特别提醒自签名证书的主机名不匹配也会导致握手失败明明打印机 IP 是对的证书里写的却是出厂序列号。这在打印服务组件里会被记成“认证失败”误导很多人去查账号密码。如果你用的是带证书的设备先检查证书里的 Common Name 是否与访问 IP 一致再检查系统信任库。证书问题不解决后面所有属性请求都不会成功。5.5 设置属性后打印机“选择忽略”Finishings与media现象提交作业时带上finishings4表示装订和mediaiso_a4_210x297mm打印机打出来却没有装订纸张也不是标准 A4。原因没有先看打印机的finishings-supported、media-supported或者设备要求用finishings-col、media-col这类集合属性而不是简单属性。解决先用Get-Printer-Attributes把支持列表拉出来再按支持列表提交。不同厂商对装订、折页这类能力的定义差异很大同一台机器的固件升级前后也可能改属性结构。有的设备只认media-col里的media结构体你只传media字符串时它会静默忽略。遇到这类情况不要盲目加大参数先用ipptool发一个只带requested-attributes finishings-supported的请求把枚举值记下来。属性协商本来就是 IPP 的强项我们却经常把它当普通 HTTP 表单处理这大概是这个协议最大的“人文陷阱”。6. 进阶把IPP当服务来调试学会这三个技能少翻车6.1 用 tcpdump 只抓 631 端口比看驱动日志快驱动日志往往只告诉你“作业错误”不告诉你打印机到底回了什么。遇到奇怪问题时我习惯先抓包tcpdump -i eth0 -s 0 -w /tmp/ipp.pcap port 631把文件留给抓包工具去解析重点看 IPP 响应里的状态码和job-state-reasons。抓包的好处是能看到客户端实际发出的属性很多“打印机不听话”其实是客户端传错属性名。6.2 把 ipptool 请求存成测试文件回归验证不再靠手敲我一般会把Get-Printer-Attributes和Print-Job写进两个独立文件存成/tmp/getattrs.test和/tmp/printjob.test。调试设备时每次只需ipptool -tv ipp://$DEVICE_IP/ipp/print /tmp/getattrs.test这样变量只出现在命令行里测试文件作为资产留档同一台设备升级固件后可以用它快速验证能力有没有变。没有测试文件每次手敲 heredoc很容易漏掉attributes-charset或printer-uri。6.3 验证端到端能力、提交、队列三连查我的验证顺序固定是先看printer-state再看document-format-supported提交后查Get-Jobs。任何一步不通过直接看对应属性不猜原因。这套流程在接入新设备时最多十分钟跑完。这几次踩坑后我养成了一个习惯凡是路由器和打印设备过来第一件事先跑一遍Get-Printer-Attributes留档很多配置问题在第一步就能看出来。希望帮到你。本文还有配套的精品资源点击获取
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表