본문 바로가기
language/java

🧾 Zipher 프로토콜 - 텍스트커맨드 통신 _ 저울라벨프린터용 _ 요청과 응답 유틸 함수 - Java 소스 샘플

by 죄니안죄니 2025. 4. 7.

Zipher 프로토콜은 문자열 기반으로 요청과 응답을 보내는 통신 규약이다. 요청 형식과 응답 형식이 프로토콜 문서에 나와있기 때문에, 이에 맞춰 Java에서 명령어를 전송하고 응답을 파싱하는 유틸 함수를 만들어서 사용하면 코드가 깔끔해진다. 

ASCII / UNICODE 모두 대응 가능한 구조로 만들고, 실제 실무에서 바로 쓸 수 있게 예외 처리까지 포함


✅ 1. sendCommand(String command) 유틸 함수 예제

import java.io.*;
import java.net.Socket;

public class ZipherClient {

    private final String printerIp;
    private final int printerPort;
    private final String encoding; // "US-ASCII" 또는 "UTF-16LE"

    public ZipherClient(String ip, int port, String encoding) {
        this.printerIp = ip;
        this.printerPort = port;
        this.encoding = encoding;
    }

    /**
     * Zipher 명령어 전송 및 응답 수신
     */
    public String sendCommand(String command) throws IOException {
        try (Socket socket = new Socket(printerIp, printerPort);
             BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), encoding));
             BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), encoding))) {

            String finalCommand = command + "\\r"; // 반드시 \\r 로 끝나야 함
            writer.write(finalCommand);
            writer.flush();

            String response = reader.readLine(); // Zipher 응답은 \\r 기준으로 한 줄
            return response;
        }
    }
}

✅ 2. 응답 파싱 유틸: parseResponse(String response)

public class ZipherResponseParser {

    public enum ResponseType {
        ACK, ERR, STS, UNKNOWN
    }

    public static ResponseType parseResponseType(String response) { //응담은 문자열로 돌아옴. 응답타입을 유형화. 이후 swtich-case등으로 처리 할 수 있게 해줌
        if (response == null) return ResponseType.UNKNOWN;
        if (response.equals("ACK")) return ResponseType.ACK;
        if (response.equals("ERR")) return ResponseType.ERR;
        if (response.startsWith("STS|")) return ResponseType.STS; //열거형
        return ResponseType.UNKNOWN; //응답은 반드시 돌아옴
    }

    public static void handleResponse(String response) { //응답을 케이스별로 처리하는 부분
        switch (parseResponseType(response)) {
            case ACK:
                System.out.println("✅ 명령어 정상 처리됨 (ACK)");
                break;
            case ERR:
                System.err.println("❌ 명령어 처리 실패 (ERR)");
                break;
            case STS:
                System.out.println("📡 프린터 상태 응답: " + response);
                // 추가 파싱 예시
                parseStatus(response); //STS... 응답인 경우 해석이 필요하기 때문에 별도 함수로 처리
                break;
            case UNKNOWN:
                System.err.println("❓ 알 수 없는 응답: " + response);
        }
    }

    private static void parseStatus(String response) {
        // 예시: STS|3|0|WeightJob|100|200
        String[] parts = response.split("\\|"); //문자열 | 로 끊어서 배열생성
        if (parts.length >= 6) {
            String statusCode = parts[1]; // 프린터 상태 코드. 예: 3 = 정상 작동 중
            String errorCode = parts[2]; // 0 : 에러 코드
            String jobName = parts[3]; // 현재 선택된 작업
            String batchCount = parts[4]; // 현재 배치 수량
            String totalCount = parts[5]; // 총 수량

            System.out.printf("▶ 상태: %s, 에러: %s, 작업명: %s, 인쇄 수량: %s/%s%n",
                    statusCode, errorCode, jobName, batchCount, totalCount);
            // ▶ 상태: 3, 에러: 0, 작업명: WeightJob, 인쇄 수량: 100/200
        }
    }
}

✅ 이 코드의 실무 장점

기능 설명
명령 성공 여부 판단 ACK/ERR 구분 가능
프린터 상태 실시간 분석 STS 응답 파싱으로 대시보드에 표시 가능
확장성 다른 응답 타입 (예: GFT, GWN 등) 추가하기 쉬움
유지보수 편리 응답 처리 로직이 명확하게 나눠져 있음 (OOP 구조)

추가할 사항 

 

  • ACK 이후 추가 명령 자동 전송 로직 (연속 처리)
  • REST API 응답에 맞게 변환 (JsonResult, DTO 등)

 


✅ 예시 사용법 (전체 흐름)

public class Main {
    public static void main(String[] args) {
        ZipherClient client = new ZipherClient("192.168.0.100", 3003, "UTF-16LE"); // 또는 "US-ASCII"

        try {
            String response = client.sendCommand("SLA|WeightJob|weight=12.34kg|label=안녕하세요");
            ZipherResponseParser.handleResponse(response);

            String printResponse = client.sendCommand("PRN");
            ZipherResponseParser.handleResponse(printResponse);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

✅ 보너스: 통신 실패 시 예외 메시지 처리 팁

catch (IOException e) {
    System.err.println("🚨 프린터 연결 실패 또는 응답 없음: " + e.getMessage());
}

✅ 정리

구성 클래스/함수

명령어 전송 ZipherClient.sendCommand()
응답 파싱 ZipherResponseParser.handleResponse()
응답 종류 구분 ACK / ERR / STS
인코딩 대응 "US-ASCII" / "UTF-16LE" 모두 가능

💬 이 구조는 그대로 Spring Boot API나 실시간 백엔드에 적용할 수 있습니다.

댓글