打印机USB驱动开发之实现打印服务器

suoniao 2021-04-30
需要:0索币

      前不久财务买了个打印机,然后呢,又不想在自己电脑上进行共享(要求贼高),怕电脑卡。然你呢,把这需求和供应商说了,然后给搞来了一个叫“打印服务器”的神器。
这小东西把USB打印机插上面,不需要给打印服务器装驱动(驱动是安装自己电脑上,这个和普通的网络打印机一样),就能够实现网络打印了。反正我认为很有意思,猜测这东西可能和串口服务器一样,只是单纯转发,而并不需要提供复杂的服务。
 (图片已打码,仅做拓扑图展示)
像普通的打印机共享,基本都是基于一定的协议的。比如samba协议,就常见的Windows共享协议,创建共享打印机进网上邻居双击安装打印机就可以使用了。还有是http共享打印机,这个是cups可以创建的共享打印机,可以通过一个http的url链接进行打印,并且支持使用代{过}{滤}理服务器。
而9100端口,常见于本身就是网络打印机的打印机,公司里十分常见。支持postscript等脚本,通过9100发送给打印机后,打印机就能打印出来。原理简单,稳定,成本低廉,有比较多的优势,所以被广泛的使用。
USB打印机转成9100的网络打印机,在Linux上应该是比较容易实现的,因为有一群大神开发了cups这牛物。但如果考虑移植性和轻便,以及乐趣,自然是要自己实现才比较有意思。

[section .正文]
作为一只“栈溢出工程师”,凡事讲究亲力亲为是我们的准则。
对于设计验证和实现,首先考虑验证程序简单,并且能够实现跨平台。首选qt,libusb本身是个C库,提供的是C的头文件,所以选用C/C++写会避免不少麻烦。然后qt能够实现不同系统上包括UI和网络代码的一致性。
关于libusb,他是一个比较有名的跨平台USB库,这套库支持win、linux、mac os、bsd等操作系统。知名的开源开发环境Arduino就是通过libusb库来实现atmage32u4这种mcu下载程序的。
但,libusb有分两个主流的版本,一个是libusb-0.1(简写为libusb0,Arduino使用的就是0.1版本的库)还有个是libusb-1.0(Linux2.6之后的版本基本上都只用1.0了,并且包管理器里0.1的devel版本已经不包含头文件了。mac os x中brew可以安装的是1.0.22版本,freebsd也是提供的1.0版本)。可见1.0版本已是主流,考虑兼容性的话个人建议使用1.0版本。
Windows上移植的libusb,libusb-win32是0.1的,另外还有WinUSB(libusb),来自github官方版本,可以详见https://github.com/libusb/libusb/wiki/Windows,也可以看一下zadig(https://zadig.akeo.ie/)这个软件上面提供的介绍。这软件安装USB驱动非常方便,并且开源了他的核心代码,为作者点赞。

[section .验证]
验证1,先写一个USB版的HelloWorld,由于第一次写USB程序,先从简单的开始。
列出VID&PID,USB设备的核心应该就是这个了,当一个不明物体插进USB后,首先系统会获取这个VID和PID,并且自动的搜索驱动。VID(idVendor)是主要识别生产厂商的,PID(idProduct)则是负责识别产品。
这两个东西在一起组成了,USB的唯一ID,重名的几率非常的低。因为同一家厂商是不会做出PID相同的东西的。


其次需要知道的东西是interface(MI,Muti-Interface?),还有endpoint。下面程序是列出打印机的interface和endpoint,操作读写USB设备时,必不可少的参数。


验证2,使用 "nc -l -p 9100>文件" 命令把打印机驱动发送给打印机的数据给保存下来。然后尝试直接把这个数据给发送到USB端口。



验证3,使用qt创建一个监听9100端口的服务器,将读取到的数据,发送到USB端口。



[section .后续]
后续最想做的就是想用esp32-s2来重新实现这么个功能,虽然esp32的RAM不大,但优化的好的话,应该是能实现打印服务器的。s2版本的话支持IP协议栈和USB OTG(USB HOST和USB DEVICE),可行性还是很高的,并且成本可能只需要20-30元。
使用MTK的OpenWrt之类的软路由,或者全志的开发板也能实现,但是毕竟价位不低。并且有现成套件,移植意义不是很大。
另外就是这种打印转发在连续打印时会有点小问题,需要实现队列或者缓冲池,然后适的重新对包进行切片。
根据抓包可以看出,PJL命令(我手头这台是HP的打印机,别的打印机可能会使用不同的命令)比较多,有固定的切片长度。但是通过网络发送的话PJL命令是连续的,所以实现对命令的重切片是非常有必要。


[section .感言]
USB真的是很棒的东西呢,记得小时候家里的电脑只有PS2接口和软驱(黄金奔腾PRO 200MHz),还尝试过PS2转USB来插入奇怪的东西,显然只能使用键盘鼠标。

曾经的美好时光依旧是记忆如新,下次来尝试一下PS2接口设备?

原文地址:https://www.52pojie.cn/thread-1393313-1-1.html

回帖
  • 消灭零回复
相关主题
打印机USB驱动开发之实现打印服务器 0
Qt利用QPrinter实现小票打印部分的代码 0
Qt读取打印机设备列表QPrinterInfo类实现 0
打印机USB驱动开发之实现打印服务器 0
Qt利用QLabel组件来显示图片 0
TableView自定义代理QStyledItemDelegate实现ComboBox 0
Qt利用QGraphicsView类实现图片放大缩小平移显示 0
Qt实现非阻塞延迟方法sleep 0
海康相机SDK的C++对应的接口 0
Qt实现webdav客户端功能支持https协议的webdav客户端 0
CHKDSK解决 移动硬盘只能看见盘符其它信息都看不见另外双击也打不开 0
gogs一直报errror:dial tcp xxx.xxx.xxx.xxx 宿主机的ip 0
索鸟快传2.1.2发布 0
索鸟快传2.1.1发布 0
Qt操作windows注册表的方法 bat从注册表中将键值删除 0
重写QSqlQueryModel实现QTableView显示图片 0
QLocalServer基于本地套接字socket的服务端server 0
Qt使用动态库的方法 QLibrary库的典型用法 0
QT实现视频播放器界面开发 0
QTableview实现鼠标放上面显示不同颜色 0
相关主题
打印机USB驱动开发之实现打印服务器 0
Qt利用QLabel组件来显示图片 0
TableView自定义代理QStyledItemDelegate实现ComboBox 0
Qt利用QGraphicsView类实现图片放大缩小平移显示 0
Qt实现非阻塞延迟方法sleep 0
海康相机SDK的C++对应的接口 0
Qt实现webdav客户端功能支持https协议的webdav客户端 0
CHKDSK解决 移动硬盘只能看见盘符其它信息都看不见另外双击也打不开 0
gogs一直报errror:dial tcp xxx.xxx.xxx.xxx 宿主机的ip 0
索鸟快传2.1.2发布 0
索鸟快传2.1.1发布 0
Qt操作windows注册表的方法 bat从注册表中将键值删除 0
重写QSqlQueryModel实现QTableView显示图片 0
QLocalServer基于本地套接字socket的服务端server 0
Qt使用动态库的方法 QLibrary库的典型用法 0
QT实现视频播放器界面开发 0
QTableview实现鼠标放上面显示不同颜色 0
Qt的QTableView自定义委托详解 0
QTableView利用自定义委托实现日期显示下拉菜单文字颜色等 0
Qt利用QApplication::sendEvent和QMouseEvent模拟鼠标点击事件 0