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

0 996
索鸟 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

回帖
  • 消灭零回复
相关主题
2020年最新最新Kubernetes视频教程(K8s)教程 2
程序员转型之制作网课变现,月入过万告别996 1
索鸟快传2.0发布啦 1
两个不同网络的电脑怎么实现文件的互相访问呢? 1
网盘多账号登录软件 1
Java实战闲云旅游项目基于vue+element-ui 1
单点登录技术解决方案基于OAuth2.0的网关鉴权RSA算法生成令牌 1
QT5获取剪贴板上文本信息QT设置剪贴板内容 1
springboot2实战在线购物系统电商系统 1
python web实战之爱家租房项目 1
windows COM实用入门教程 1
C++游戏开发之C++实现的水果忍者游戏 1
计算机视觉库opencv教程 1
node.js实战图书管理系统express框架实现 1
C++实战教程之远程桌面远程控制实战 1
相关主题
PHP7报A non well formed numeric value encountered 0
Linux系统下关闭mongodb的几种命令分享 0
mongodb删除数据、删除集合、删除数据库的命令 0
Git&Github极速入门与攻坚实战课程 0
python爬虫教程使用Django和scrapy实现 0
libnetsnmpmibs.so.31: cannot open shared object file 0
数据结构和算法视频教程 0
redis的hash结构怎么删除数据呢? 0
C++和LUA解析器的数据交互实战视频 0
mongodb errmsg" : "too many users are authenticated 0
C++基础入门视频教程 0
用30个小时精通C++视频教程可能吗? 0
C++分布式多线程游戏服务器开发视频教程socket tcp boost库 0
C++培训教程就业班教程 0
layui的util工具格式时间戳为字符串 0
C++实战教程之远程桌面远程控制实战 1
网络安全培训视频教程 0
LINUX_C++软件工程师视频教程高级项目实战 0
C++高级数据结构与算法视频教程 0
跨域问题很头疼?通过配置nginx轻松解决ajax跨域问题 0