一、Linux打印
1.1 Linux打印简介
首先需要了解的是,打印在Unix世界的演化中总是围绕着PostScript页面描述语言展开的。该语言是由Adobe公司开发的,它是一个成熟的、用于描述一个文档每一页面内容的程序语言。它是一种与设备无关的打印机语言,即在定义图像时可以根本不考虑输出设备的特性(如打印机的分辨率、纸张大小等),而且它对文本和图形实行同样的处理过程,这就给处理字体带来了极大的灵活性。通过PS驱动程序,各种不同的应用软件将各自的数据转换成PostScript格式。
如今很多打印机中都有一个嵌入式的PostScript解释器,它负责使用PostScript将页面在打印纸上再现出来。现在,所有桌面Linux应用程序都有一个打印选项,可以生成PostScript数据来打印整页的文档。
这种方法和其它面向桌面的操作系统有很大的不同,也正是它让Unix打印落下了不易使用的名声。在Windows和Mac OS中有整合得非常好的API供应用程序使用,通常情况下都可以为打印机提供一个接口,以让应用程序不用关心设备的具备细节。此外,打印API通常也是和图形API整合在一起,并且可用于在屏幕上显示。这其中部分功能已经在X11中实现了。
大部分Unix系统是提交任务至队列中,并且希望它能够正确地打印出来。但是并没有一种统一的收集打印机信息或工作状态的方法,这严重影响了那些需要提供打印能力的Linux应用程序。
在Linux中,虽然PostScript是产生打印文档的事实上的标准,但打印机本身却并不需要知道PostScript,因为这需要使用到相对比较昂贵的技术。在一般情况下,尤其是在低端打印机中,PostScript数据要被翻译成打印机本地的页面描述语言。这是通过使用一个特殊的转换过滤器来完成的。一般而言,一个过滤器实际上就是一个特殊的程序,它可以处理输入的数据,并且输出经过加工的数据。现在,Linux打印系统中使用着各种不同的过滤器:转换过滤器、I/O过程器(负责将数据传送至设备)、处理过滤器(转换文档数据)。
打印系统的基础是一个假脱机程序(Spooler)。它可以管理打印任务队列,而一个队列通常和一个打印机相关联,并且用户提交的任务都是按照先进先出的原则来处理的。当一个打印任务被处理时,任务中的数据在送达打印机前一般都要通过一定数量的过滤器。Unix打印假脱机程序有很多种形式,在此将关注目前在Linux系统中使用广泛的几种形式:
(1)BSD LPD打印系统
(2)LPRng打印系统
(3)通用Unix打印系统(CUPS)
1.2 Linux打印原理
在Linux下采用假脱机(spooling)打印方法,当用户需要打印一个文件时,该文件并不直接送到打印机,而是送到spool目录下,然后由一个负责打印的后台进程把这些数据送入打印机。
Linux对每台打印机都定义了一个打印缓冲区,打印机守护程序经常扫描打印缓冲区以查看有无要打印的新文件。如果存在,就按先进先出的顺序打印缓冲区中的文件。
Linux系统除了可以在本地打印机上打印外,还可以通过网络打印机远程打印。
Linux系统上的打印原理如下:
各种类型的文档经由一个(或一些)转换程序转换成用户正在使用的打印机可以认识的格式,即用各种类型的打印机语言描述的流,系统将这个流直接发送到打印机端口,由打印机对其进行解释并形成硬拷贝。
目前大多数Linux系统以下面的流程来实现文档到打印机语言的转换:
普通文本文件和各种类型的图形由适当的转换程序转换成PostScript文件,有些应用程序将其输出直接写成PostScript文件,这些PostScript文件经由一个作为打印机过滤器的应用程序Ghostscript转换成打印机语言。因此,如果系统的打印系统已经配置成使用Ghostsript作为打印过滤器,应用程序要实现的就是输出合乎程序要求和语法的PostScript文件。
1.3 Linux打印流程
在打印过程中,通常是应用程序产生输出并以管道的方式传送给lpr或者直接应用lpr打印一个文件。lpr与打印机后台服务程序通过网络进行连接并进行通信,传送相应的打印数据和打印选项。打印机后台服务程序将在相应的spooler目录存储打印信息,在输出设备可以利用的情况下将打印任务送给打印设备。
普通文本文件和各种类型的图形由适当的转换程序转换成PostScript文件,有些应用程序将其输出直接写成PostScript文件,这些PostScript文件经由一个作为打印机过滤器的应用程序Ghostscript转换成打印机语言。因此,如果系统的打印系统已经配置成使用Ghostsript作为打印过滤器,应用程序要实现的就是输出合乎程序要求和语法的PostScript文件。 1.3 Linux打印流程
在打印过程中,通常是应用程序产生输出并以管道的方式传送给lpr或者直接应用lpr打印一个文件。lpr与打印机后台服务程序通过网络进行连接并进行通信,传送相应的打印数据和打印选项。打印机后台服务程序将在相应的spooler目录存储打印信息,在输出设备可以利用的情况下将打印任务送给打印设备。
二、通用Unix打印系统(CUPS)
2.1 CUPS简介
CUPS使用的是IPP(网络打印协议)标准,这是从HTTP中衍生出来的IETF协议。CUPS后台程序可以接受IPP请求,并且将其作为和客户端应用程序进行通信的主要方法。作为一个Internet协议,IPP使得在广域网上配置打印服务器变得非常容易。CUPS也支持其它可以和打印机进行通信的流行协议,因此也可以将其作为一个连接不支持IPP协议打印机的一个桥梁。和其所基于的HTTP协议一样,IPP也可以通过使用认证和SSL连接来加强安全性。CUPS本身都支持这些功能,也就是说它可以进行安全打印。
CUPS采用的另外一个标准是PPD(PostScript Printer Definition)文件格式,这是Adobe另外一个用于PostScript打印机的标准。
CUPS还采用了很多过滤器用于传送数据至打印机的方法。与BSD类的假脱机程序不同的是,这是通过一种更加智能的方式来完成的。下面是在CUPS中可用的部分过滤器:
1.后端过滤器。它可以提供最终数据进行传送的端点。这些过滤器可用于并口、TCP/IP套接字连接、LPD和其它端点的连接。
2.文档转换过滤器。该过滤器是作为CUPS一个标准配置一起发行的。它可以转换图像、ASCⅡ文本、PDF文件和HP-GL/2矢量文档至PostScript。
3.接口过滤器。它可以将文档从PostScript转换至其它过渡的文件格式。
和其它的打印系统一样,为了能够在非PostScript打印机上正确打印,翻译过滤器也是必须的。CUPS允许PPD文件记述用于将文档换成设备本地语言的过滤器,比如:
*cupsFilter: ”application/vnd.cups-raster 0 rastertohp
这是用于HP Deskjet打印机的一个PPD文件。它的意思是rastertohp程序(这是一个过滤器,通过位于/usr/lib/cups/filter)将把MIME数据类型的文件“application/vnd.cups-raster”作为输入,并且将其转换成可直接送至打印机的格式,在此就是HP PCL数据。
CUPS可以进行打印机分类,该功能最初用于Sy stem V打印系统中。它可以将打印机按组“分类”,并且自动执行负载均衡功能。一个分类可以将任务传送至一个正常的队列中,一旦任务提交,就会被分配给第一个可用的打印机来执行打印任务。
CUPS一个非常有用的功能就是可以自动进行网络配置。通过广播协议,所有位于同一个局域网的CUPS监控程序都可以相互通信,某一服务器上的队列配置可以被浏览,并可用于其它的系统之上。CUPS也可以为那些位于不同服务器上却有着同样名字的打印机提供一个“默认分类” ,并自动为其提供负载平衡。CUPS也支持LSP(服务定位协议),该协议可以发送广播以表明自己已经在线。
在客户端,CUPS有LPD类和System V类的接口,这就意味着它可以提供lpr、lpq、lp、lpstat等系统命对于IPP客户端和CUPS监控程序进行通信的过程来说,所有这些命令都是非常重要的。
CUPS还有一个基于Web的系统管理界面,可以直接通过Web浏览器进行配置和管理,或者检查打印机的状态。这显然要比使用命令或直接通过编辑/etc/cups/printers.conf文件来定义队列要直观得多。
CUPS打印不需要将输出格式限制在PostScript。虽然其它一些打印系统也不一定有这样的限制,但是CUPS却将它做得更容易。前面我们已经看到了用于CUPS的PPD文件中是如何指定一个转换过滤器的,以及这些内容如何包含在MIME中。CUPS广泛使用了MIME类型来决定打印机间任务提交和最终数据之间的数据流。过滤器可以在*.convs文件(通常位于/etc/cups)中定义,该文件可以描述每一个过滤器程序作为接收输入的数据类型及作为输出的数据类型。对于一给定类型的任务,CUPS会聪明地在一个过滤器链中做出决定。
2.1应用程序接口
在Unix世界里,PostScript语言仍然是主要用于打印的接口。所有主要的应用程序都会输出通用的PostScript页面,而这些PostScript经过打印系统处理后再被打印出来。这显然有很大的局限性,因为应用程序并没有一种统一的、查询打印功能或获知任务是否被正确打印的途径。有少量的应用程序可以使用PPD文件来访问打印机功能,不过StarOffice和OpenOffice并不包含在内。
现在情况还是有所改观。比如,CUPS提供了一个基本的C API,它可以让应用程序更简单地和打印系统进行整合。这个API包含了通过IPP和CUPS监控程序进行通信的功能,以及读取和解析PPD文件的功能,这样,应用程序就具备了收集打印机详细信息的能力。但对于应用程序开发人员来说还有很大的局限性,因为它只能在CUPS和类似的IPP服务器上工作。
在软件方面,为了使打印更加容易,现在GNOME和KDE桌面项目都包含了一个中间层,分别是KDEPrint和GNOME。这些框架的目的是通过抽出基本的打印系统,为应用程序提供一个统一的API。
2.2 CUPS支持的打印方式
(1)本地打印方式,包括本地并口、串口、USB等
(2)远程打印方式
(3)网络打印方式
2.3 CUPS的结构与原理
CUPS的结构如下图所示。
CUPS调度程序(Scheduler)-cupsd,完成分派打印任务,处理管理命令、提供打印状态和通知用户等。它的具体功能如下:
1. 控制本地打印机及网络上其他打印机的访问权限。
2. 接收用户传送的文件来打印。这些要打印的要求称为jobs。为用户传送的文件分配任务编号(job-id),并根据任务的属性(优先级)插入到当前任务队列等待打印。
3. 利用队列来防止多个用户同时访问同一台打印机。
4. 在输出时打出header page(也称做banner或burst pages)。这样,用户可以在厚厚一打纸张中找出他们自己所打印的东西。
5. 为连接在串口上的打印机设置适当的通信参数。
6. 通过网络将工作送给另一台机器上的CUPS 后台打印系统。
7. 执行特定的过滤器,让你的工作可以兼容于使用不同打印机语言的打印机。
8. 统计打印机的使用情况。
通过一个配置文件(/etc/cups/printers.conf)或提供特定的过滤器,你可以启用CUPS系统在不同的打印机上执行上面全部或部分的功能。
命令(Berkeley and System V Commands),提交打印任务和检查打印机状态。
文档转换过滤器和接口过滤器(filters)。文档转换过滤器是作为CUPS一个标准配置一起发行的。它可以转换图像、ASCⅡ文本、PDF文件和HP-GL/2矢量文档至PostScript。接口过滤可以将文档从PostScript转换至其它过渡的文件格式。
后端过滤器(backends)。它可以提供最终数据进行传送的端点。这些连接器可用于并口、TCP/IP套接字连接、LPD和其它端点的连接。包括parallel,ipp,serial,usb,socket等。在采用CUPS进行打印过程中,将由这些连接器直接打开设备端口。
2.4 CUPS基本设置
要使用CUPS进行打印工作,你需要同时设置好你的打印机硬件和CUPS软件。设置分为两大部分:
1. 简单的打印机设置,
2. 高级打印机设置
2.4.1简单的打印机设置
如何配置打印机硬件和CUPS软件。包括:
(1)硬件设置这一节说明如何将打印机接到计算机的连接端口。
(2)软件设置这一节说明如何设置CUPS后台打印系统的配置文件(/etc/cups/printers.conf)。
CUPS可以通过网页浏览器从打印服务器的631端口访问。打开浏览器,指向http://127.0.0.1:631 ,点击Manage Printer。这里你可以找到你新安装的打印机,配置打印机并测试一个页面。也可以从命令行管理CUPS。
对于CUPS来说,只有root用户才能配置打印机,在浏览器界面下root用户可以根据打印机的型号进行配置,其中包括选择打印机端口、根据打印机的型号选择相应的驱动。如果要使用另一型号的打印机,则需要为该打印机建立新的配置或者修改现在默认打印机配置。
推荐的打印驱动程序是根据选定的打印机型号而选择的。打印驱动程序把你想打印的数据处理成打印机能够理解的格式。由于本地打印机是直接连接到你的计算机上的,你需要一个打印驱动程序来处理发送给打印机的数据。
同时需要说明的是,root用户可以配置多个打印机(本地、远程、网络),在某一时刻只有一个打印机配置文件起作用(默认打印配置),如果需要使用另一打印配置则需要更改默认配置。所有打印机的配置信息存放在一个配置文件中(/etc/cups/prnter.conf)。
2.5 CUPS打印方式
(1)通过cat等命令直接送往/dev/lp0等打印端口
该方式不需要特定的打印系统支持,如果以终端用户登陆使用vncviewer和Xvnc则启动的cat进程将属于Xvnc的子进程,该进程直到打印完成之后才会结束。
(2)通过使用打印系统提供的打印命令lpr等
对于CUPS打印系统,lpr的作用是通过IPP协议与cupsd后台服务进行通信,提交相应的请求(request),通过类似于HTTP协议的请求与应答提交相应的打印作业的内容,包括建立打印临时文件,使用何种打印配置,传送打印文件内容。cupsd接受到请求后,根据提交的请求信息形成打印任务,为打印任务分配id,根据任务优先级插入到统一的打印任务队列中。cupsd循环地检测打印队列状况,根据任务的属性和打印机的属性决定是否进行打印操作。
(3)通过应用程序进行打印
当CUPS打印系统设置完毕后,应用程序使用打印系统进行打印可分为两种情况,第一种情况就是某些应用程序(Mozilla、OpenOffice、Emacs)自动的调用CUPS的打印命令lpr将文档送往默认打印机进行打印;第二类应用程序(xpdf)将文档内容转换成后缀为ps的文件,然后再手工调用CUPS打印命令进行打印。
值得一提的是CUPS系统打印测试页方式不同于以上的打印方式,因为测试页文档是一个固定的文档(testprint.ps),通过浏览器方式打印测试页通过IPP协议并调用printers.cgi将打印任务提交给CUPS后台服务程序。
2.6 CUPS原理分析
为了对打印任务进行控制,Linux将打印系统分为上下两部分,上半部分和需打印的应用程序合作,负责打印任务的生成和管理工作,分别由过滤器和打印系统后台程序(cupsd,lpd)完成,下半部分负责与打印机通信,由运行于内核空间的驱动程序lp完成,打印机后台程序负责在过滤器和lp之间传递打印任务。
2.6.1CUPS后台服务程序-cupsd分析
(1) 检查命令行参数
(2) 设置相应的参数:时域、文件最大数目
(3) 读取配置文件
(4) 初始化认证
(5) 加载所有的打印任务:初始化打印作业队列,启动打印任务
(6) 进入永久循环状态
◆检查是否需要重新加载“服务器”的配置文件,如果需要,则进行以下操作:
◆如果当前“客户端”大于0则依次设置“客户端”链接状态,否则重新读取配置文件;
◆通过seclect()监听多个“客户端”链接;
◆循环处理监听信息并决定是否接收来自“客户端”的请求;
◆循环处理被接收的“客户端”请求,读“客户端”信息,然后往“客户端”写信息,最后检查活动的以及老的“客户端”请求;
◆循环检测来自作业过滤器返回的状态,读取状态信息;
◆根据需要更新浏览列表;
◆更新未决的打印文档;
◆每5分钟更新一次root用户授权;
(7)出现异常情况下退出了(6)的循环过程,则删除授权信息,关闭所有的“客户端”链接,关闭监听端口