【发布时间】:2019-01-17 12:50:25
【问题描述】:
我们正在切换到一个系统,在该系统中,我们的托运人需要在他们今后发送的产品上放置带有我们商品 ID 的条形码。我们的管理层愿意借给他们 Brother TD-4100N 标签打印机,条件是他们不会将其用于打印我们的条形码以外的其他目的,现在我的任务是编写一个允许他们打印我们的条形码的接口。
然而,他们的核心竞争力在于运输管理,而不是 IT 管理,因此我必须让事情变得简单且独立于平台 - 或者至少尽可能独立于平台。这里的想法是能够通过以太网插入其中一台打印机而无需任何设置 - 尽可能简单。没有司机,什么都没有,保持简单,愚蠢。我只想使用以太网端口和套接字。有了这个具有以太网端口并接受 ESC/P 代码的特定型号,这不应该那么难,对吧?
在使用一台测试机一周后,我对 ESC/P 代码和 Brother 的专有扩展(至少他们声称是)了解了足够多的知识,可以用 C 编写一个小框架。以所需格式打印条形码( Code128) 本身不会造成问题,但它周围的簿记会造成问题;此时我在我的第三本手册中声称只需发送命令“\x1B\x69\x53”(ESC i S)应该会导致打印机向我发送其当前状态的 32 字节记录,但对于某些打印机根本不想向我发送它的运行情况的原因:
char buffer_send[] = "x1B\x69\x53";
send(sock_jet,buffer_send,sizeof(buffer_send) - 1,0);
char buffer[32];
memset(buffer,0,sizeof(buffer));
recv(sock_jet,buffer,sizeof(buffer),0);
fprintf
(
stderr,
"%02x%02x%02x%02x%02x%02x%02x%02x\n",
buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7]
);
fprintf
(
stderr,
"%02x%02x%02x%02x%02x%02x%02x%02x\n",
buffer[8],buffer[9],buffer[10],buffer[11],buffer[12],buffer[13],buffer[14],buffer[15]
);
fprintf
(
stderr,
"%02x%02x%02x%02x%02x%02x%02x%02x\n",
buffer[16],buffer[17],buffer[18],buffer[19],buffer[20],buffer[21],buffer[22],buffer[23]
);
fprintf
(
stderr,
"%02x%02x%02x%02x%02x%02x%02x%02x\n",
buffer[24],buffer[25],buffer[26],buffer[27],buffer[28],buffer[29],buffer[30],buffer[31]
);
这段代码只是暂停了一段时间,直到超时或其他情况发生,recv 不会将任何数据写入我的缓冲区:
0000000000000000
0000000000000000
0000000000000000
0000000000000000
而且我显然不是唯一一个遇到这种问题的人。这个 Ruby Python 包 (https://pypi.org/project/brotherprint/#files) 声称专门为 Brother 打印机提供服务,但我从未见过他们收到任何数据(至少在 brotherprint/brotherprint.py 中)。事实上,我什至没有看到他们正确拼写“receive”。
在 SO (operating printer with php socket programming) 上,有人试图在 PHP 中做同样的事情,而我正试图在 C 中做同样的事情 - 他们遇到了与我完全相同的问题,打印机拒绝给他们状态数据。该解决方案似乎涉及从端口 9100 切换到端口 515 并使用不同的协议,虽然我看到打印机上打开了端口 515,但我从未看到该打印机的任何输出,在纸上或在插座上。此时我会联系 Brother 支持,但我已经打开了 另一个 工单,因为他们的 另一个 打印机似乎在将状态报告发送回给杯子。
我尝试在我的有效负载末尾添加一个 NUL 字节,以防打印机正在等待页面馈送,但这也没有奏效。再说一遍:将条形码打印到该死的东西上是可行的,因此 IP、端口和连接至少在一定程度上可以正常工作 - 但接收状态报告却不行。
我的程序中的strace:
connect(3, {sa_family=AF_INET, sin_port=htons(9100), sin_addr=inet_addr("192.168.XXX.XXX")}, 16) = 0
sendto(3, "\33iS", 3, 0, NULL, 0) = 3
recvfrom(3, <blocks here for minutes> "", 32, 0, NULL, NULL) = 0
write(2, "0000000000000000\n", 170000000000000000
) = 17
write(2, "0000000000000000\n", 170000000000000000
) = 17
write(2, "0000000000000000\n", 170000000000000000
) = 17
write(2, "0000000000000000\n", 170000000000000000
) = 17
close(3)
以及我正在使用的主要手册:https://download.brother.com/welcome/docp000579/cv_td4000_eng_escp_120.pdf(搜索“ESC i S”)。
【问题讨论】:
-
好吧,尽管判断更好,但我一直在给 Brother 支持部门发送电子邮件。他们告诉我,他们真的不知道该怎么办,但一直在将我的邮件转发到日本,在那里它可能会因为语言障碍而被误解(我一直在用我的母语邮寄,这不是' t 很容易翻译成日文),被忽略,然后在很长一段时间后拿起。他们可能会默默地解决问题,然后默默地发布固件更新,我将忽略它,因为它太长了,我会一直告诉人们这是一个硬件问题。
标签: c sockets printing cross-platform