본문 바로가기
hardware_integration/zipher

소켓통신은 뭐지? 시리얼포트값 읽기 왜 프론트단이 아닌 서버단에서만 하는거지?

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

역할설명

 

✅ 1. 소켓 통신(Socket Communication) 이란?

📌 정의

양쪽 컴퓨터(또는 장비)가 네트워크상에서 직접 데이터를 주고받기 위한 통로를 만드는 것이에요. 국제통신규약에 따라. 내부적으로 InputStream, OutputStream으로 구성돼요. 스트림의 기본 단위는 byte 배열, 즉 버퍼입니다. (모든 소켓은 내부적으로 버퍼로 구현. 버퍼라서 소켓이 아니고 버퍼는 수단임)

Java에서 소켓 데이터를 주고받는 도구 (InputStream, OutputStream)

메모리상에서 임시로 데이터를 저장하는 공간

byte[] buffer = new byte[1024]; inputStream.read(buffer);

→ 한 번에 하나씩 1바이트씩 주고받지 않고,

→ 어느 정도 모아서(또는 준비해서) 한 덩어리씩 주고받습니다.

✔ 모든 소켓 통신이 버퍼를 쓰는 이유는 성능 때문이에요. 전송 최적화 기법이 버퍼 

 


Zipher 프린터와 Java 서버가 “전화 연결”처럼 통신하는 구조라고 보면 돼요.

  • Java에서는 이런 식으로 열죠:
Socket socket = new Socket("192.168.0.100", 3003);   // 1. 연결 (TCP 규약에 따라 3-way handshake) // 2. 데이터 전송 (Socket → OutputStream → byte buffer → 전송) // 3. 데이터 수신 (InputStream → byte buffer → 문자열로 해석)
  • 위 코드는 192.168.0.100 IP의 장비(예: 프린터)의 3003번 포트로 연결하는 거예요.

📶 소켓 통신 구성

역할 설명
클라이언트 요청하는 쪽 (예: Java 서버가 프린터에 명령 전송)
서버 요청을 받는 쪽 (예: 프린터가 명령 수신 후 응답)
포트 주소 중 하나 (예: 3003 포트에서 프린터 대기 중)

🔁 예시 흐름

Java 
→ 소켓 연결(IP:192.168.0.100, Port:3003) 
→ "SEL|WeightLabel|중량=12.34kg\r" 전송 ← "ACK\r" 응답 수신 
→ "PRN\r" 전송 ← "ACK\r" 응답 수신
 

💬 왜 소켓을 쓰나요?

  • 빠르다 (HTTP보다 빠름)
  • 양방향 실시간 통신 가능
  • Zipher 프린터는 기본적으로 TCP/IP 소켓으로 대기 중

✅ 2. Java에서 Socket 통신 구현 방법

Zipher는 TCP 기반이라 (연결만드는 방법, 데이터 전송방법, 순서보장, 오류처리 방법을 정해놓은 국제적으로 표준화된 규약에 따라 만들었기 때문에) Java에서 Socket 클래스로(가 그 규약대로 구현해둔 도구라서) 쉽게 연결 가능해요.

new Socket(ip, port) //자바가 TCP연결 열어서 스트림으로 전송/수신 가능한 상태가 된다.

( 신뢰성 보장형 프로토콜. 정확한 명령 처리가 필요한 장비무조건 TCP를 사용해야 함. 반대개념 UDP)

소켓 통신은 내부적으로 데이터를 전부 byte배열(buffer)로 주고받습니다. 

socket.getOutputStream().write("SLA|Job|label=한라봉\r".getBytes("UTF-16LE")); //인코딩 방식을 넘기지 않으면 JVM설정(OS)따라서 윈도우의 경우 기본 MS949 일 가능성이 높음

☕ Java 예제 코드 (Zipher 명령어 보내기)

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

public class ZipherClient {
    public static void main(String[] args) {
        String printerIp = "192.168.0.100";
        int printerPort = 3003;

        try (Socket socket = new Socket(printerIp, printerPort);
             BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "US-ASCII"));
             BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "US-ASCII"))) {

            // 1. 작업 선택
            send(writer, reader, "SLA|WeightJob|weight=12.34kg");

            // 2. 출력 실행
            send(writer, reader, "PRN");

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

    private static void send(BufferedWriter writer, BufferedReader reader, String command) throws IOException {
        writer.write(command + "\\r");  // \\r은 필수!
        writer.flush();

        String response = reader.readLine();
        System.out.println(">> " + command);
        System.out.println("<< " + response);  // 예: ACK 또는 ERR
    }
}

✅ 3. Socket 통신이 빠른 이유

🔥 이유는 "직접 연결 + 스트리밍"이기 때문이에요.

방식 과정 속도 비교

HTTP 요청 → 연결 → 헤더 → 데이터 → 응답 느림 (수십 ~ 수백 ms)
Socket 이미 연결된 상태에서 데이터만 송수신 빠름 (수 ms, 실시간 수준)
    • Socket은 연결만 되면 바로 송수신 가능
    • HTTP는 요청마다 연결을 새로 열어야 함
    • Zipher도 실시간 통신(TCP 기반)이기 때문에 Socket과 궁합이 좋음

✅ 4. 저울까지 연동한 전체 구조

    •  

Zipher 외에 저울 연동까지 포함된 실무 구조는 아래와 같아요:

  • [저울 (RS232)] ← 시리얼 통신 → [Java 백엔드] ←→ [Vue 프론트]
                                              ↓
                                     (TCP) → [Zipher 프린터]

📌 각 컴포넌트 설명

구성 요소역할
저울 RS232(시리얼)로 무게 측정값 전송
Java 백엔드 저울과 시리얼 연결, 중량 수신 + Vue에 전달 + Zipher 명령 생성
Vue 프론트 현재 중량 보여주기, 인쇄 요청 버튼
Zipher 프린터 Java로부터 명령 수신 후 라벨 인쇄

🛠 실무 구현 포인트

  • Java는 jSerialComm 같은 라이브러리로 저울 데이터 읽음
  • 읽은 무게를 메모리에 저장하거나 WebSocket/REST로 Vue에 보냄
  • Vue에서 "인쇄" 버튼 → Java로 POST /print → Java가 Zipher에 SEL, PRN 명령 전송

저울 연동은 Java에서 처리하는 게 맞을까, Vue에서?

✅ 정답: Java가 저울과 직접 연결하는 게 맞습니다


 

이유 설명
Vue는 웹 브라우저에서 돌아감 → 시리얼 포트를 직접 읽을 수 없음 (보안 제한)
Java는 서버 또는 PC 앱 → 시리얼 통신 가능 (jSerialComm 등)
Vue는 표시용 + 전송용 → 무게만 보여주고 Java API에 전달해서 DB 저장


✅ 보너스: 동작 흐름 예시

1. 저울 → Java로 "12.34kg" 전송 2. Vue에 현재 중량 표시됨 3. 사용자가 Vue에서 "출력" 버튼 클릭 4. Java가 Zipher 프린터에 명령 전송: SEL|WeightJob|weight=12.34kg\r PRN\r 5. 프린터에서 라벨 인쇄됨

💬 추가학습

  • 저울 연동을 위한 Java 시리얼통신 코드 예제
  • Vue + WebSocket 실시간 무게 표시 예제
  • Spring Boot API + 프린터 모듈 구성

댓글