1

Background

I am trying to create a java application to send ZPL command to a ZPL printer and get a label printed. I set up a ZPL emulator(https://chrome.google.com/webstore/detail/zpl-printer/phoidlklenidapnijkabnfdgmadlcmjo) by following this post : Emulate ZPL printer

Issue

  1. After setting the emulator up and add it as zpl printer via mac Printer&Scanner , enter image description here

I try to use lp command to print it. it is stable the reliable:

lp -o "raw" -q1 -d zpl <<< "^XA\n^FO50,60^A0,40^FDWorld Best Griddle^FS\n^FO60,120^BY3^BCN,60,,,,A^FD1234ABC^FS\n^FO25,25^GB380,200,2^FS\n^XZ"

enter image description here

  1. However, my use case is send the command to a printer remotely on the network, Therefore I need to create a java application to send the Zpl command to the printer. It succeeds initially, then it randomly get splitted:
    java code:
import java.io.*;
import java.net.*;
class TCPClient
{
    public static void main (String argv[]) throws Exception
    {

        Socket clientSocket=new Socket("127.0.0.1",9100);

        DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream() );
        try {
            outToServer.writeBytes("^XA\n^FO50,60^A0,40^FDWorld Best Griddle^FS\n^FO60,120^BY3^BCN,60,,,,A^FD1234ABC^FS\n^FO25,25^GB380,200,2^FS\n^XZ");
                
        } catch (Throwable e) {
            System.out.println(e);
        }

        outToServer.flush();
        outToServer.close();
        clientSocket.close();
//        outToServer.flush();

    }
}

Result:

enter image description here

enter image description here

So quite often, it succeeds once and then following 2 or 3 printing get fragmented or failed. I suspect it might be the socket TCP fragmentation issue. or there any socket option I can configure? But not sure how to solve it. Can anyone help here?

Update:

I try to use wireshark. The issue resides in the TCP package size:

For lp command, everything is sent as one single pack: enter image description here

As for java app, it is broken down into smaller packs for some reason. enter image description here

But I still don't know how to configure the pack size. Also it confuses me a lot why Java app will break the data packet to like 1 byte or two byte sized?

Stan
  • 602
  • 6
  • 23
  • Basically now my question is how we can diable TCP fragmentation in java socket programming – Stan Jan 27 '23 at 08:23
  • Like limiting the data content to one single TCP packet – Stan Jan 27 '23 at 08:40
  • It has nothing to do with the size of the TCP packets. TCP is not a message oriented protocol but rather a stream protocol, so no successful protocol built on top of TCP depends on receiving individual packets of any particular size. – President James K. Polk Jan 27 '23 at 15:34
  • @PresidentJamesK.Polk Then it might be the issue of the ZPL emulator? like it just cannot handle the tcp message properly. Like not knowing how to assemble the packet together – Stan Jan 28 '23 at 06:05
  • I think the issue is that I didn't use LPR protocol... – Stan Jan 29 '23 at 23:50

1 Answers1

0

I think you are using a wrong method to send printing job. I'm not sure lp command uses Socket connection. Try calling lp from Java using Runtime.getRuntime().exec:

String cmd = "lp -o \"raw\" -q1 -d zpl <<< \"^XA\n^FO50,60^A0,40^FDWorld Best Griddle^FS\n^FO60,120^BY3^BCN,60,,,,A^FD1234ABC^FS\n^FO25,25^GB380,200,2^FS\n^XZ\"";
Runtime.getRuntime().exec(String.format(cmd));
ZuzEL
  • 12,768
  • 8
  • 47
  • 68
  • But my use case is that printer is remote. Can only be identified by IP. – Stan Jan 27 '23 at 08:32
  • @Stan that doesn't matter. Add a remote printer to your system the same way you add a local one and send jobs to the printer through your system. You can also use `lp` command to add printers: https://docs.oracle.com/cd/E19455-01/805-7229/printsetup-42445/index.html – ZuzEL Jan 27 '23 at 08:39
  • ok, my use case is a microservice will be deployed into GCP cloud run(serverless). And printers are on-prem whose IPs are assigned by DHCP. It means microservice has to reach out to the DHCP server first to get a IP for printer then send the command to the printer directly. – Stan Jan 27 '23 at 08:42
  • @Stan I think this is a completely different problem. Try calling your printer remotely first. If you can do that, you can always add new remote printer to your system from java using the guide above and immediately call it via LPR protocol. – ZuzEL Jan 27 '23 at 08:56
  • How can we add the printer to cloud run? we cannot configure each time we receive a print request, right? – Stan Jan 27 '23 at 09:12
  • 1
    @Stan you can run preconfigured docker container – ZuzEL Jan 27 '23 at 11:32