장비 통신 프로토콜 설계 방법: Packet 구조·Command·ACK·CRC 직접 만들기
장비 통신 프로토콜 설계 방법: Packet 구조·Command·ACK·CRC 직접 만들기#
1장 자체 Protocol은 어디서부터 설계해야 할까#
새로운 장비를 개발한다고 생각해보겠습니다.
주차관제 시스템이라면 다음 장비가 있을 수 있습니다.
RFID Reader
↓
Controller
↓
Central Server
↓
Gate Controller
↓
Barrier Gate장비를 RS-485나 TCP로 연결했다고 해서 서로 자동으로 대화할 수 있는 것은 아닙니다.
먼저 다음을 약속해야 합니다.
어디서 Message가 시작되는가?
누구에게 보내는가?
무슨 Command인가?
Data 길이는 얼마인가?
정상적으로 받았는가?
오류가 발생하면 어떻게 표현하는가?
같은 명령이 두 번 들어오면 어떻게 처리하는가?이 약속 전체가 장비 통신 Protocol입니다.
2장 먼저 업무 흐름부터 정의한다#
Protocol Format부터 만들기 전에 장비가 실제로 어떤 대화를 해야 하는지 정하는 것이 좋습니다.
예를 들어 차량이 들어오는 상황을 생각해보겠습니다.
차량 감지
↓
카드 또는 차량번호 인식
↓
출입 권한 확인
↓
Gate Open 요청
↓
Gate 동작
↓
실제 Open 상태 확인여기서 필요한 Message를 추출합니다.
예:
AUTH_REQUEST
AUTH_RESPONSE
OPEN_GATE
CLOSE_GATE
GET_STATUS
DEVICE_STATUS
HEARTBEAT즉 Command Code부터 만드는 것이 아니라 실제 업무 흐름에서 필요한 Command를 먼저 찾아야 합니다.
3장 하나의 Packet에는 무엇이 들어가야 할까#
장비 Protocol을 처음 설계할 때 다음 구조를 출발점으로 생각할 수 있습니다.
[HEADER]
[VERSION]
[LENGTH]
[ADDRESS]
[SEQUENCE]
[COMMAND]
[PAYLOAD]
[CRC]각 Field는 서로 다른 역할을 합니다.
| Field | 역할 |
|---|---|
| Header | Frame 시작 식별 |
| Version | Protocol Version |
| Length | Message 길이 |
| Address | 대상 장비 식별 |
| Sequence | 요청·응답 연결 및 중복 확인 |
| Command | 수행할 동작 |
| Payload | 실제 Data |
| CRC | 전송 오류 검출 |
모든 Protocol에 이 Field가 반드시 필요한 것은 아닙니다.
시스템 규모와 요구사항에 따라 단순화하거나 확장할 수 있습니다.
4장 Header는 Frame 시작을 찾게 해준다#
Binary Protocol에서는 다음과 같은 Header를 사용할 수 있습니다.
AA 55전체 Frame:
AA 55 ...Receiver는 Byte Stream을 읽다가:
AA 55를 발견하면 새 Frame이 시작된 것으로 판단할 수 있습니다.
이런 값은 흔히:
Header
Magic Number
Signature
Sync Word등으로 부릅니다.
Header만 믿으면 안 되는 이유#
Payload 내부에도 우연히:
AA 55가 나타날 수 있습니다.
따라서 Header를 발견한 뒤에도:
Version
Length
Command
CRC를 추가로 확인해 실제 Frame인지 검증하는 것이 좋습니다.
5장 Version Field는 미래의 변경을 대비한다#
초기 Protocol을:
Version = 1로 시작했다고 하겠습니다.
몇 년 뒤 Packet 구조가 변경됐습니다.
기존 장비:
Protocol Version 1신규 장비:
Protocol Version 2라면 Receiver가 Version을 보고 적절한 Parser를 선택하거나 지원하지 않는 버전을 거부할 수 있습니다.
예:
VERSION 01
→ Parser V1
VERSION 02
→ Parser V2Version Field가 없으면 장비 교체나 Firmware Update 후 호환성 문제가 훨씬 복잡해질 수 있습니다.
6장 Length는 Message 경계를 찾는 핵심 정보다#
가변 길이 Payload를 사용한다면 Length가 중요합니다.
예:
AA 55 01 00 08 ...여기서:
00 08이 Length라고 하겠습니다.
Receiver는 이 값을 이용해:
앞으로 몇 Byte를 기다려야 하는가?를 판단할 수 있습니다.
Length가 무엇을 의미하는지 명확하게 정의한다#
가장 흔한 실수 중 하나입니다.
Length가:
Payload 길이인지,
Command + Payload 길이인지,
전체 Packet 길이인지 반드시 문서에 명시해야 합니다.
예:
Length
=
Address부터 CRC 직전까지의 Byte 수처럼 정확하게 정의하는 것이 좋습니다.
7장 Address는 장비를 식별한다#
여러 장비가 하나의 RS-485 Bus를 사용한다면 Address가 필요할 수 있습니다.
Master
│
├─ Gate 01
├─ Gate 02
├─ Reader 03
└─ Sensor 04Packet:
ADDRESS = 03이면 Reader 03을 대상으로 하는 Message로 해석할 수 있습니다.
Source와 Destination을 둘 다 둘 수도 있다#
복잡한 시스템에서는:
SOURCE
DESTINATION을 별도로 둘 수 있습니다.
예:
SRC = 01
DST = 05이렇게 하면 Gateway나 Multi-controller 구조에서도 Message 경로를 더 명확하게 추적할 수 있습니다.
8장 Command Code는 무엇을 하라는 명령인지 정의한다#
Command Table을 만들어야 합니다.
예:
| Code | Command |
|---|---|
0x10 |
AUTH_REQUEST |
0x11 |
AUTH_RESPONSE |
0x20 |
OPEN_GATE |
0x21 |
CLOSE_GATE |
0x30 |
GET_STATUS |
0x31 |
STATUS_RESPONSE |
0x40 |
HEARTBEAT |
Command 값 자체보다 더 중요한 것은 각 Command가 어떤 Payload를 가지는지 명확히 정의하는 것입니다.
9장 Payload는 Command별로 구조를 정의한다#
예를 들어:
CMD = 0x20
OPEN_GATE라면 Payload를 다음처럼 정의할 수 있습니다.
BYTE 0
Gate Number
BYTE 1
Open Mode
BYTE 2~3
Open Duration반면:
CMD = 0x30
GET_STATUS는 Payload가 없을 수도 있습니다.
즉:
Command
↓
Payload Format 결정구조가 됩니다.
10장 데이터 타입도 Protocol 문서에 명확히 적는다#
Field가 단순히:
Temperature
2 Bytes라고 적혀 있으면 부족합니다.
다음을 함께 정의해야 합니다.
Signed / Unsigned
Integer / Float
Endian
Scale
Unit예:
Temperature
Type:
Signed 16-bit Integer
Endian:
Big Endian
Scale:
0.1
Unit:
°CRaw 값이:
00 FD라면:
253
×
0.1
=
25.3°C처럼 해석할 수 있습니다.
11장 문자열 Encoding도 정해야 한다#
Text Data가 있다면:
ASCII
UTF-8
UTF-16중 무엇을 사용할지 정합니다.
예를 들어 차량번호처럼 한글이 필요한 Data를 순수 ASCII로 표현할 수는 없습니다.
이 경우 UTF-8 같은 Encoding을 고려할 수 있습니다.
또 다음도 결정해야 합니다.
문자열 앞에 Length를 둘 것인가?
NUL로 끝낼 것인가?
고정 길이 Field인가?가변 길이 문자열이라면 Length Prefix가 관리하기 편리한 경우가 많습니다.
12장 Sequence Number를 처음부터 넣는 것이 좋다#
요청과 응답을 연결해야 한다면 Sequence Number가 유용합니다.
Request:
SEQ = 42
CMD = OPEN_GATEResponse:
SEQ = 42
STATUS = SUCCESSServer는:
Request 42
↔
Response 42를 연결할 수 있습니다.
Sequence Number는 다음에도 도움이 됩니다.
Duplicate 검출
Retry 확인
응답 Matching
Log 추적13장 ACK와 실행 완료를 분리해서 설계한다#
장비 Protocol에서 매우 중요한 부분입니다.
Server가:
OPEN_GATE를 보냈습니다.
Device가 Packet을 정상적으로 받으면:
ACK를 보낼 수 있습니다.
하지만 실제 Gate가 열리기까지는 시간이 필요합니다.
따라서:
OPEN_GATE
↓
ACK
↓
Motor 동작
↓
Open Sensor 확인
↓
OPEN_COMPLETE처럼 나누는 방식이 더 정확할 수 있습니다.
ACK와 물리 동작 완료는 같은 상태가 아닙니다.
14장 NACK와 Error Code를 함께 설계한다#
단순히:
NACK만 보내면 원인을 알기 어렵습니다.
예:
| Error Code | 의미 |
|---|---|
0x01 |
INVALID_COMMAND |
0x02 |
INVALID_PARAMETER |
0x03 |
CRC_ERROR |
0x04 |
DEVICE_BUSY |
0x05 |
SAFETY_INTERLOCK |
0x06 |
UNSUPPORTED_VERSION |
이렇게 하면 Server가 오류 종류에 따라 대응할 수 있습니다.
예:
CRC_ERROR
→ Retry 가능
INVALID_COMMAND
→ Retry 의미 없음
DEVICE_BUSY
→ 잠시 후 재시도
SAFETY_INTERLOCK
→ 현재 장비 상태 확인15장 Timeout과 Retry를 Protocol에 포함한다#
Response가 오지 않는다고 무한정 기다릴 수 없습니다.
예:
Response Timeout
500ms
Maximum Retry
3회같은 정책을 정의할 수 있습니다.
하지만 숫자를 임의로 정하면 안 됩니다.
다음을 고려합니다.
Baud Rate
Packet Size
장비 처리 시간
Bus 장비 수
Gateway 지연
Network Latency
실제 물리 동작 시간그리고:
통신 ACK Timeout과:
물리 동작 Completion Timeout을 별도로 관리하는 것이 좋습니다.
16장 Retry 때문에 같은 명령이 두 번 실행되지 않게 한다#
가장 중요한 설계 문제 중 하나입니다.
Server:
SEQ 42
OPEN_GATEDevice가 명령을 실행했습니다.
그런데 ACK가 손실되었습니다.
Server가 다시 보냅니다.
SEQ 42
OPEN_GATEDevice가 다시 Motor를 움직여서는 안 될 수 있습니다.
따라서 최근 Sequence와 처리 결과를 저장해:
SEQ 42
이미 처리됨
↓
기존 ACK 재전송처럼 처리할 수 있습니다.
이것이 Duplicate Handling입니다.
17장 CRC는 어떤 범위를 계산할지 명확하게 한다#
Frame을 다음처럼 설계했다고 하겠습니다.
[HEADER]
[VERSION]
[LENGTH]
[ADDRESS]
[SEQ]
[COMMAND]
[PAYLOAD]
[CRC]CRC를:
VERSION부터 PAYLOAD까지계산할지:
HEADER부터 PAYLOAD까지계산할지를 반드시 정의해야 합니다.
Protocol 문서에는 다음을 명시합니다.
CRC Type
Polynomial
Initial Value
RefIn
RefOut
Final XOR
Calculation Range
CRC Byte OrderCRC-16이라고만 적는 것은 부족합니다.
18장 CRC와 보안 무결성은 다르다#
CRC가 정상이라고 Packet을 신뢰할 수 있는 것은 아닙니다.
공격자는 Packet을 변경한 뒤 CRC를 다시 계산할 수 있습니다.
따라서 보안이 필요한 Protocol에서는 별도로:
Authentication
Authorization
MAC / HMAC
Encryption
Replay Protection을 고려합니다.
예를 들어:
[HEADER]
[PAYLOAD]
[CRC]
[AUTH TAG]같은 구조를 설계할 수도 있습니다.
실제 적용 방식은 시스템 보안 요구사항에 따라 결정합니다.
19장 Timestamp와 Nonce도 고려할 수 있다#
특히 제어 명령에서는 과거 Packet을 다시 전송하는 Replay Attack을 고려해야 할 수 있습니다.
예:
SEQ
TIMESTAMP
NONCE
COMMAND
PAYLOAD
AUTH TAG처럼 구성하면 동일 Packet의 재사용을 탐지하는 데 활용할 수 있습니다.
Sequence Number만으로는 충분하지 않을 수 있습니다.
특히 Sequence가:
0 ~ 255처럼 반복된다면 더 그렇습니다.
20장 전체 Frame을 하나 만들어보자#
교육용 Protocol을 다음처럼 설계해보겠습니다.
| Offset | 길이 | Field |
|---|---|---|
| 0 | 2 | Header |
| 2 | 1 | Version |
| 3 | 2 | Length |
| 5 | 1 | Address |
| 6 | 2 | Sequence |
| 8 | 1 | Command |
| 9~ | 가변 | Payload |
| 마지막 2 | 2 | CRC |
구조:
[AA 55]
[VER]
[LENGTH]
[ADDR]
[SEQ]
[CMD]
[PAYLOAD]
[CRC16]예:
AA 55
01
00 0C
01
00 2A
20
01 00 05
AB CD이 값들은 구조 설명을 위한 가상의 예입니다.
21장 OPEN_GATE Command를 설계해보자#
Command:
0x20
OPEN_GATEPayload:
BYTE 0
Gate ID
BYTE 1
Mode
BYTE 2~3
Duration예:
01 00 00 05의미:
Gate 1
Normal Mode
Open Duration 5단 Duration의 단위가:
초인지
100ms 단위인지
millisecond인지반드시 문서에 적어야 합니다.
22장 Response도 명확하게 설계한다#
Request:
SEQ 42
CMD
OPEN_GATEResponse:
SEQ 42
CMD
OPEN_GATE_RESPONSE
STATUS
ACCEPTED이후 실제 Gate가 열리면 Event를 보냅니다.
SEQ 42
EVENT
GATE_OPENED이렇게 하면:
Command 수신
Command 실행 승인
실제 동작 완료를 각각 구분할 수 있습니다.
23장 상태 기계까지 함께 설계하면 더 안전하다#
Gate 상태:
CLOSED
OPENING
OPEN
CLOSING
ERROR라고 정의합니다.
현재:
OPENING상태에서 다시:
OPEN_GATE가 들어오면:
IN_PROGRESS를 반환할 수 있습니다.
현재:
OPEN상태라면:
ALREADY_OPEN을 반환할 수 있습니다.
Protocol은 단순한 Packet Format뿐 아니라 장비 상태와 Command의 관계까지 정의하면 훨씬 명확해집니다.
24장 Heartbeat도 필요할 수 있다#
TCP Connection이 살아 있다고 장비 Application이 정상이라는 보장은 없습니다.
따라서:
HEARTBEAT
HEARTBEAT_ACK을 정의할 수 있습니다.
예:
Server
→ HEARTBEAT SEQ 120
Device
→ HEARTBEAT_ACK SEQ 120이를 통해 Application Level 상태를 확인할 수 있습니다.
25장 Protocol Version이 다르면 어떻게 처리할까#
Device:
Version 1Server:
Version 2라고 하겠습니다.
다음 정책 중 하나를 선택할 수 있습니다.
완전 거부
하위 버전 호환
Negotiation
특정 Command만 제한예:
ERROR
UNSUPPORTED_VERSION처럼 명확하게 반환하면 장애 분석이 쉬워집니다.
26장 Version 변경 규칙도 정해둔다#
예를 들어 다음처럼 운영할 수 있습니다.
1.0
→ 기존 Field 유지
1.1
→ 선택 Field 추가
2.0
→ 호환되지 않는 Packet 구조 변경또는 단순 정수 Version을 사용할 수도 있습니다.
중요한 것은 Version Number 자체보다 변경 정책을 문서화하는 것입니다.
27장 Command Code는 처음부터 공간을 나누면 편하다#
예:
0x10 ~ 0x1F
인증
0x20 ~ 0x2F
Gate Control
0x30 ~ 0x3F
Status
0x40 ~ 0x4F
Event
0xF0 ~ 0xFF
System / Error이렇게 영역을 나누면 Command가 늘어날 때 관리하기 쉽습니다.
28장 Reserved 영역도 남겨둔다#
처음부터 모든 값을 사용하지 않는 것이 좋습니다.
예:
0x20
OPEN_GATE
0x21
CLOSE_GATE
0x22 ~ 0x2F
Reserved향후 기능이 추가되었을 때 기존 Command를 변경하지 않고 확장할 수 있습니다.
29장 최대 Packet 크기를 반드시 정한다#
Length가 2 Byte라면 이론상 큰 값을 표현할 수 있습니다.
하지만 장비가 실제로 그렇게 큰 Message를 처리할 수 있다는 뜻은 아닙니다.
예:
MAX_PACKET_SIZE
4096 Bytes처럼 제한을 두는 것이 좋습니다.
Receiver는:
Length > 4096이면 바로:
INVALID_LENGTH로 처리할 수 있습니다.
이는 안정성과 보안 모두에 중요합니다.
30장 Parser는 방어적으로 설계한다#
Receiver가 Packet을 받으면 다음 순서로 확인할 수 있습니다.
Header 확인
↓
Version 확인
↓
Length 범위 확인
↓
전체 Packet 수신 확인
↓
CRC 확인
↓
Address 확인
↓
Command 확인
↓
Payload Length 확인
↓
Payload 값 검증
↓
Command 처리Payload부터 바로 처리해서는 안 됩니다.
31장 TCP라면 Stream Parser까지 설계해야 한다#
TCP 위에 Protocol을 올린다면:
send 한 번
=
Message 한 개라고 가정하면 안 됩니다.
Receiver는:
TCP Stream
↓
Buffer
↓
Header 검색
↓
Length 확인
↓
Frame 추출
↓
CRC 검증방식으로 처리해야 합니다.
즉 Protocol Specification에는 Frame Format뿐 아니라 Stream Parsing Rule도 포함하는 것이 좋습니다.
32장 RS-485라면 Address와 응답 Timing을 더 신경 써야 한다#
RS-485 Multi-drop Bus:
Master
│
├─ Device 1
├─ Device 2
├─ Device 3
└─ Device 4에서는:
Address
Response Delay
Turnaround Time
Timeout
Retry가 중요합니다.
여러 장비가 동시에 응답하지 않도록 Protocol 규칙을 명확하게 해야 합니다.
33장 Broadcast Command는 매우 조심해서 설계한다#
예를 들어:
Address FF
=
Broadcast를 정의할 수 있습니다.
하지만:
OPEN_GATE같은 물리 제어 Command를 Broadcast로 허용하는 것은 위험할 수 있습니다.
Broadcast가 필요한 경우에도:
TIME_SYNC
DISCOVERY
CONFIG_QUERY처럼 상대적으로 안전한 명령 중심으로 제한하는 방식을 고려할 수 있습니다.
34장 주차관제 시스템의 Message 흐름 예#
전체 흐름을 단순화하면:
Reader
↓
AUTH_REQUEST
↓
Server
↓
AUTH_RESPONSE
↓
Controller
↓
OPEN_GATE
↓
Gate
↓
ACK
↓
실제 Gate Open
↓
GATE_OPENED Event각 Message에는:
Address
Sequence
Command
Payload
CRC를 포함할 수 있습니다.
35장 Protocol 로그 형식도 처음부터 설계한다#
좋은 Log는 다음처럼 남길 수 있습니다.
2026-09-24 15:10:21.123
DIR
TX
DEVICE
01
SEQ
42
CMD
OPEN_GATE
RAW
AA 55 ...
RESULT
SENT응답:
2026-09-24 15:10:21.151
DIR
RX
DEVICE
01
SEQ
42
CMD
OPEN_GATE_RESPONSE
STATUS
ACCEPTED
CRC
OKProtocol과 Log Format을 함께 설계하면 장애 분석이 훨씬 쉬워집니다.
36장 개인정보가 들어가는 Field도 설계 단계에서 관리한다#
주차관제 Packet에는:
차량번호
Card ID
회원 ID
입출차 시각같은 정보가 포함될 수 있습니다.
따라서 Protocol 설계 단계에서:
정말 필요한 Data인가?
평문 전송해도 되는가?
Log에 남겨도 되는가?
Masking이 필요한가?
보관 기간은 얼마인가?를 검토해야 합니다.
37장 암호화 여부도 Transport와 함께 결정한다#
TCP를 사용한다고 자동으로 암호화되는 것은 아닙니다.
필요하다면:
TLS
VPN
전용 보안 Gateway등을 사용할 수 있습니다.
RS-485 같은 Legacy Bus에서는 End-to-End Security를 Application Protocol 수준에서 별도로 설계해야 하는 경우도 있습니다.
38장 Protocol 테스트 케이스를 함께 만든다#
Protocol 문서만 만드는 것으로 끝내지 않습니다.
정상 Case:
정상 Header
정상 Length
정상 Command
정상 CRC뿐 아니라 오류 Case도 만듭니다.
잘못된 Header
지원하지 않는 Version
Length 초과
잘못된 Command
CRC Error
Duplicate Sequence
Timeout
잘못된 Address
잘못된 Payload이런 Test Case가 있어야 실제 구현의 품질을 검증할 수 있습니다.
39장 시험망에서 일부러 Packet을 망가뜨려본다#
예를 들어 정상 Packet:
AA 55 01 00 0C ...에서 Version을 변경합니다.
AA 55 FF 00 0C ...예상:
UNSUPPORTED_VERSIONCRC를 변경합니다.
예상:
CRC_ERRORLength를 과도하게 크게 만듭니다.
예상:
INVALID_LENGTH이런 방식으로 Protocol의 Error Handling을 검증합니다.
40장 Packet Format보다 Error Handling이 더 중요할 때도 있다#
정상 상황에서는 대부분의 Protocol이 잘 동작합니다.
진짜 차이는 다음과 같은 상황에서 나타납니다.
Packet 일부만 수신
CRC Error
Unknown Command
Device Busy
Timeout
Duplicate
Restart
Version 불일치따라서 Protocol 설계 문서는 정상 Frame보다 오류 상황에서 어떻게 복구하는지를 더 상세하게 적는 것이 좋습니다.
41장 Protocol 문서에는 무엇을 적어야 할까#
최소한 다음 항목을 포함하는 것이 좋습니다.
1. Protocol 개요
2. Transport
RS-485 / TCP 등
3. Serial / Network 설정
4. Frame Format
5. Field Offset
6. Data Type
7. Endianness
8. Command Table
9. Response Format
10. Error Code
11. Sequence 규칙
12. CRC Algorithm
13. Timeout
14. Retry
15. Duplicate 처리
16. Version 정책
17. Security
18. Test Vector
19. State Machine
20. Example Packet이 문서가 개발자와 현장 기술자 사이의 공통 언어가 됩니다.
42장 Byte Offset 표를 만들어두면 좋다#
예:
| Offset | Length | Field | 설명 |
|---|---|---|---|
| 0 | 2 | Header | AA 55 |
| 2 | 1 | Version | Protocol Version |
| 3 | 2 | Length | Big Endian |
| 5 | 1 | Address | Device Address |
| 6 | 2 | Sequence | Request ID |
| 8 | 1 | Command | Command Code |
| 9 | N | Payload | Command별 정의 |
| 9+N | 2 | CRC | CRC-16 |
이 표 하나만 있어도 Packet Parser 구현과 Hex Dump 분석이 훨씬 쉬워집니다.
43장 Known Test Vector도 문서에 포함한다#
예:
Input:
AA 55 01 00 0C 01 00 2A 20 01 00 05
Expected CRC:
12 34처럼 정해진 Input과 기대 결과를 제공합니다.
개발자는 자신의 CRC 구현이 맞는지 바로 검증할 수 있습니다.
44장 흔히 하는 설계 실수#
44.1 Length가 무엇을 의미하는지 명확하지 않다#
Parser 구현마다 결과가 달라집니다.
44.2 Endianness를 문서에 적지 않는다#
다중 Byte 값이 서로 다르게 해석됩니다.
44.3 ACK를 성공 완료로 정의해버린다#
실제 물리 동작 실패를 놓칠 수 있습니다.
44.4 Timeout이 하나뿐이다#
통신 응답과 물리 동작 완료 시간을 분리하지 못합니다.
44.5 Duplicate 정책이 없다#
Retry로 같은 명령이 두 번 실행될 수 있습니다.
44.6 CRC만 있으면 보안된다고 생각한다#
CRC는 인증 기능이 아닙니다.
44.7 Version Field만 있고 호환 정책이 없다#
Version 번호가 있어도 실제 Upgrade 대응이 불가능합니다.
44.8 Error Code가 너무 단순하다#
모든 실패가 ERROR 하나면 장애 원인을 찾기 어렵습니다.
45장 프로토콜 설계 체크리스트#
□ 어떤 Transport를 사용할 것인가?
□ Message 시작은 어떻게 찾는가?
□ Length는 무엇을 의미하는가?
□ Maximum Packet Size는 얼마인가?
□ Byte Order는 무엇인가?
□ Address는 필요한가?
□ Sequence Number가 필요한가?
□ Command 영역을 어떻게 나눌 것인가?
□ Payload Data Type은 어떻게 정의하는가?
□ 문자열 Encoding은 무엇인가?
□ CRC Algorithm과 계산 범위는 무엇인가?
□ ACK는 무엇을 의미하는가?
□ 실제 동작 완료는 어떻게 확인하는가?
□ NACK에 Error Code가 있는가?
□ Timeout은 얼마인가?
□ Retry는 몇 번인가?
□ Duplicate를 어떻게 처리하는가?
□ Version 호환 정책이 있는가?
□ Replay Protection이 필요한가?
□ Authentication·Encryption이 필요한가?
□ Raw Packet Log를 어떻게 남기는가?
□ 개인정보 Field는 어떻게 보호하는가?
□ Test Vector가 준비되어 있는가?46장 자기 점검#
46.1 Protocol 설계에서 Packet Format보다 먼저 정해야 할 것은 무엇인가#
장비가 실제로 어떤 업무 흐름과 Command를 주고받아야 하는지 정하는 것입니다.
46.2 Length Field가 중요한 이유는 무엇인가#
가변 길이 Message에서 Parser가 Frame 경계를 정확히 판단할 수 있도록 도와주기 때문입니다.
46.3 Sequence Number는 왜 필요한가#
요청과 응답을 연결하고 Retry에 의한 Duplicate Packet을 구분하는 데 활용할 수 있기 때문입니다.
46.4 ACK만 있으면 장비 동작 성공을 판단할 수 있는가#
반드시 그렇지 않습니다.
ACK는 Packet 수신이나 Command 승인만 의미할 수 있으므로 실제 장비 상태를 별도로 확인해야 합니다.
46.5 CRC와 HMAC의 차이는 무엇인가#
CRC는 우발적인 전송 오류 검출이 목적이고 HMAC은 비밀 Key를 이용한 Message 인증과 무결성 확인이 목적입니다.
47장 이 글을 마치며#
자체 장비 Protocol을 설계한다는 것은 단순히:
AA 55 01 10 ...같은 Packet Format을 하나 만드는 일이 아닙니다.
실제로는:
업무 흐름
↓
Command
↓
Payload
↓
Address
↓
Sequence
↓
Packet Boundary
↓
CRC
↓
ACK / NACK
↓
Timeout / Retry
↓
Duplicate 처리
↓
Version
↓
Security
↓
Logging전체를 하나의 규칙으로 만드는 작업입니다.
특히 다음 다섯 가지를 기억하면 됩니다.
Protocol 설계는 Packet Format보다 실제 장비의 업무 흐름과 상태를 정의하는 것에서 시작해야 합니다.
Length·Endian·CRC 계산 범위처럼 사소해 보이는 규칙도 Byte 단위로 명확하게 문서화해야 합니다.
ACK와 실제 장비 동작 완료를 분리하고 Sequence Number와 Duplicate 처리 정책을 함께 설계해야 합니다.
Version Field를 넣는 것만으로 호환성이 해결되는 것이 아니라 변경 규칙과 하위 호환 정책까지 정의해야 합니다.
CRC는 통신 오류를 검출할 뿐 보안을 제공하지 않으므로 인증·암호화·Replay Protection은 별도로 설계해야 합니다.
결국 좋은 장비 Protocol은 가장 많은 Field를 가진 Protocol이 아닙니다.
누가 보내고, 무엇을 요청하고, 어디까지 처리됐으며, 문제가 생겼을 때 어떻게 복구해야 하는지를 개발자와 장비가 똑같이 이해할 수 있도록 명확하게 정의된 Protocol이 좋은 Protocol입니다.