ACK와 NACK란? 장비 통신에서 응답·재전송·Sequence Number 이해하기

ACK와 NACK란? 장비 통신에서 응답·재전송·Sequence Number 이해하기#

1장 명령을 보냈다고 장비가 실행했다는 뜻은 아니다#

장비 통신에서 가장 위험한 착각 중 하나는 다음과 같습니다.

명령 전송 성공
=
장비 동작 성공

예를 들어 서버가 차단기 Controller에 다음 명령을 보냈다고 하겠습니다.

OPEN_GATE

Application에서는 전송 함수가 정상적으로 끝났습니다.

send() 성공

그렇다면 차단기는 열렸을까요?

아직 알 수 없습니다.

실제 흐름에는 여러 단계가 존재합니다.

서버
↓
Command 생성
↓
통신 Driver
↓
Cable 또는 Network
↓
장비 Receiver
↓
Packet Parsing
↓
Command 처리
↓
Motor 동작
↓
Sensor 확인

중간 어느 곳에서든 문제가 생길 수 있습니다.

그래서 장비 Protocol에서는 흔히 ACK, NACK, Sequence Number, Timeout, Retry 같은 신뢰성 제어 방법을 사용합니다.


2장 ACK란 무엇인가#

ACK는 Acknowledgement의 약자로 상대가 어떤 Message를 정상적으로 받았거나 처리했다는 사실을 알려주는 응답입니다.

예:

Controller
    │
    │ OPEN_GATE
    ▼
Gate
    │
    │ ACK
    ▼
Controller

쉽게 말하면:

"받았다."

라는 신호입니다.

하지만 여기서 매우 중요한 문제가 있습니다.

ACK가 정확히 무엇을 확인했다는 뜻인지는 Protocol마다 다릅니다.


2.1 ACK가 의미할 수 있는 여러 단계#

어떤 장비에서 ACK는:

Packet을 정상적으로 받았다.

는 뜻일 수 있습니다.

다른 장비에서는:

Command를 해석했다.

일 수 있고,

또 다른 장비에서는:

Command 처리를 시작했다.

라는 뜻일 수도 있습니다.

따라서:

ACK
=
실제 장비 동작 완료

라고 바로 생각하면 안 됩니다.


3장 NACK란 무엇인가#

NACK 또는 NAK는 Negative Acknowledgement를 의미합니다.

쉽게 말하면:

"정상적으로 처리할 수 없다."

라는 응답입니다.

예:

Server
↓
SET_PARAMETER

Device
↓
NACK

NACK의 원인은 다양할 수 있습니다.

잘못된 Command

잘못된 Parameter

Checksum Error

CRC Error

Device Busy

권한 없음

지원하지 않는 기능

따라서 NACK 자체보다 함께 전달되는 Error Code가 더 중요할 수 있습니다.


4장 ACK와 NACK는 별도 Byte일 수도 있고 Packet일 수도 있다#

일부 단순 Serial Protocol에서는 ASCII Control Character를 사용할 수 있습니다.

대표적으로:

ACK
0x06

NAK
0x15

같은 형태입니다.

하지만 모든 장비가 이런 방식을 쓰는 것은 아닙니다.

현대적인 장비 Protocol에서는 다음처럼 Response Packet 안에 Status Code를 넣을 수 있습니다.

[STX]
[ADDRESS]
[COMMAND]
[STATUS]
[CHECKSUM]
[ETX]

예:

STATUS = 0x00
→ Success

STATUS = 0x01
→ Error

따라서 Protocol 문서에서 ACK/NACK가 어떤 형태로 표현되는지 먼저 확인해야 합니다.


5장 ACK를 못 받으면 어떻게 할까#

Command를 보낸 뒤 응답이 없다고 하겠습니다.

TX
OPEN_GATE

...

응답 없음

송신 측에서는 일정 시간 동안 응답을 기다립니다.

이 시간을 Response Timeout이라고 합니다.

예:

Command 전송
↓
Timer 시작
↓
ACK 기다림
↓
Timeout

Timeout이 발생하면 Protocol 정책에 따라 Retry를 수행할 수 있습니다.

OPEN_GATE
↓
Timeout
↓
OPEN_GATE 재전송

하지만 여기서 새로운 문제가 발생합니다.


6장 응답이 없다고 명령이 실행되지 않은 것은 아니다#

다음 상황을 생각해보겠습니다.

Server
│
│ OPEN_GATE
▼
Gate Controller

Gate Controller는 Command를 정상적으로 받았습니다.

그리고 실제 Gate를 열었습니다.

Gate OPEN

그런데 Controller가 보내는 ACK가 통신 중 손실됩니다.

Gate Controller
│
│ ACK
X
│
Server

Server 입장에서는:

응답 없음

입니다.

그러면 Server가 같은 Command를 다시 보낼 수 있습니다.

OPEN_GATE
Retry

여기서 Duplicate Command 문제가 발생합니다.


7장 Sequence Number가 필요한 이유#

이런 중복을 구분하기 위해 Packet에 Sequence Number를 넣을 수 있습니다.

예:

SEQ = 42
CMD = OPEN_GATE

Packet:

[ADDR][SEQ][CMD][DATA][CRC]

Server가 보냅니다.

SEQ 42
OPEN_GATE

Device가 정상적으로 처리하고:

ACK
SEQ 42

를 보냅니다.

이제 Server는:

이 ACK는
SEQ 42 Command의 응답이다.

라고 연결할 수 있습니다.


8장 Sequence Number는 응답을 요청과 연결한다#

여러 Command가 빠르게 오간다고 생각해보겠습니다.

SEQ 40 → STATUS

SEQ 41 → CONFIG

SEQ 42 → OPEN_GATE

SEQ 43 → SENSOR_READ

응답이 약간 다른 순서로 돌아올 수도 있습니다.

ACK 40

ACK 42

ACK 41

ACK 43

Sequence Number가 없다면 어떤 응답이 어떤 요청에 대한 것인지 구분하기 어려워질 수 있습니다.

하지만 Sequence Number가 있으면:

Request 42
↔
Response 42

처럼 연결할 수 있습니다.


9장 같은 Sequence Number가 다시 들어오면 어떻게 해야 할까#

Server가:

SEQ 42
OPEN_GATE

를 전송했습니다.

Device가 처리했습니다.

하지만 ACK가 손실되었습니다.

Server가 다시 보냅니다.

SEQ 42
OPEN_GATE

Device는 이때:

SEQ 42를 이미 처리했는가?

를 확인할 수 있습니다.

이미 처리했다면 다시 Motor를 움직이는 대신:

ACK SEQ 42
ALREADY_PROCESSED

같은 응답을 보내도록 설계할 수 있습니다.

이런 중복 방지 설계가 장비 제어에서는 매우 중요합니다.


10장 Idempotent란 무엇인가#

Idempotent는 같은 요청을 여러 번 수행해도 최종 결과가 한 번 수행한 것과 같도록 만드는 성질입니다.

예를 들어 Gate가 이미 열려 있다고 하겠습니다.

다시:

OPEN_GATE

Command가 들어옵니다.

안전한 설계라면:

현재 상태
OPEN

↓

추가 Motor 동작 없음

↓

ALREADY_OPEN

처럼 처리할 수 있습니다.

이 경우 같은 명령이 여러 번 들어와도 상태는 그대로 OPEN입니다.


10.1 모든 명령이 Idempotent한 것은 아니다#

예:

ADD_CREDIT +1000

이라는 Command가 있다고 하겠습니다.

같은 Command가 두 번 실행되면:

+1000
+1000
=
+2000

이 됩니다.

따라서 이런 Command는 단순하게 Retry하면 안 됩니다.

Sequence Number, Transaction ID, Duplicate Cache 등을 이용해 중복 실행을 방지해야 합니다.


11장 ACK와 실제 물리 동작 완료를 구분한다#

차단기 제어를 예로 들어보겠습니다.

Command:

OPEN_GATE

Device가 Packet을 정상적으로 받자 바로:

ACK

를 보냈다고 하겠습니다.

하지만 실제 차단기 동작은 아직 시작하지 않았을 수 있습니다.

전체 흐름:

OPEN_GATE 수신
↓
ACK
↓
안전 Sensor 확인
↓
Motor 동작
↓
Open Limit Sensor 감지
↓
OPEN_COMPLETE

이 구조라면 ACK와 OPEN_COMPLETE는 완전히 다른 의미입니다.


12장 통신 성공과 업무 성공을 분리한다#

장비 시스템에서는 다음 상태를 구분하는 것이 좋습니다.

1. Command 전송됨

2. 장비가 Command 수신

3. Command가 유효함

4. 실행 시작

5. 실제 물리 동작 완료

6. 완료 상태 보고

Application에서 이 모든 상태를:

성공

하나로 표현하면 장애 분석이 어려워집니다.

예를 들어:

COMMAND_SENT

COMMAND_ACK

EXECUTING

EXECUTED

FAILED

처럼 분리하면 현재 어디까지 진행됐는지 알 수 있습니다.


13장 NACK도 이유를 함께 보내는 것이 좋다#

단순한:

NACK

만으로는 왜 실패했는지 알 수 없습니다.

Protocol에서 다음처럼 Error Code를 함께 제공할 수 있습니다.

NACK
ERROR = 01

예시:

Code 의미 예시
0x01 잘못된 Command
0x02 잘못된 Parameter
0x03 Device Busy
0x04 안전 조건 불충족
0x05 권한 오류

실제 값은 제조사 Protocol마다 다릅니다.


14장 Response Timeout은 어떻게 정할까#

Timeout을 너무 짧게 설정하면 정상 응답까지 실패로 판단합니다.

예:

평균 응답
80ms

Timeout
50ms

라면 정상 장비에도 Retry가 반복될 수 있습니다.

반대로 너무 길면 장애 감지가 늦어집니다.

장비 실제 응답
100ms

Timeout
5000ms

이면 고장난 Device 하나 때문에 5초씩 기다리게 됩니다.


14.1 Timeout 설정에 영향을 주는 요소#

다음 요소를 봅니다.

장비 내부 처리 시간

Serial Baud Rate

Packet Length

Bus에 연결된 장비 수

Polling 구조

Network Latency

Gateway 처리 시간

안전 Sensor 확인 시간

즉:

Timeout = 500ms

같은 숫자를 다른 시스템에서 그대로 복사하는 것은 좋지 않습니다.


15장 기계의 동작 시간과 통신 응답 시간을 혼동하지 않는다#

차단기가 실제로 열리는 데:

2초

가 걸린다고 하겠습니다.

그렇다고 ACK Timeout을:

2초

로 해야 한다는 의미는 아닙니다.

Protocol이:

Command 수신
↓
20ms 후 ACK

실제 Gate Open
↓
2초 후 COMPLETE

방식이라면 두 Timer를 별도로 관리해야 합니다.

예:

ACK Timeout
100ms

Operation Timeout
3000ms

처럼 구성할 수 있습니다.


16장 Retry는 어떻게 동작할까#

가장 단순한 방식은 일정한 시간 후 다시 보내는 것입니다.

TX
↓
500ms 기다림
↓
Timeout
↓
Retry 1
↓
500ms
↓
Retry 2

예:

Maximum Retry
3회

로 제한할 수 있습니다.

무한 Retry는 일반적으로 피해야 합니다.


17장 무한 재전송이 위험한 이유#

장비가 고장난 상태에서 계속 재전송한다고 하겠습니다.

Retry
Retry
Retry
Retry
Retry
...

결과:

Bus Traffic 증가

다른 장비 통신 지연

Log 폭증

장비 부하 증가

복구 후 오래된 Command 실행 가능성

등이 생길 수 있습니다.

물리적 제어 시스템이라면 더 위험할 수 있습니다.


18장 Backoff란 무엇인가#

Retry 사이의 대기 시간을 점점 늘리는 방법을 Backoff라고 합니다.

예:

1차 Retry
100ms

2차 Retry
200ms

3차 Retry
400ms

4차 Retry
800ms

처럼 증가시킬 수 있습니다.

Network 시스템에서는 Exponential Backoff가 많이 사용됩니다.

하지만 모든 Serial Device Protocol에 반드시 필요한 것은 아닙니다.

장비와 Protocol 특성에 따라 판단해야 합니다.


19장 RS-485에서는 Retry를 더 신중하게 설계한다#

여러 Device가 하나의 RS-485 Bus를 공유한다고 하겠습니다.

Master
 │
 ├─ Device 1
 ├─ Device 2
 ├─ Device 3
 └─ Device 4

한 Device 때문에 Retry가 반복되면 전체 Bus를 오래 점유할 수 있습니다.

Device 1 요청
↓
Timeout
↓
Retry
↓
Retry
↓
Retry

Device 2는 기다림

따라서 최대 Retry와 Timeout은 전체 Polling Cycle을 고려해야 합니다.


20장 TCP가 있다면 ACK가 필요 없을까#

그렇지 않습니다.

TCP 자체에도 ACK가 존재합니다.

하지만 TCP ACK는 기본적으로:

상대 TCP Stack까지 Byte가 전달되었다는 의미입니다.

그것이:

장비 Application이 Command를 이해했다.

또는:

Motor가 실제로 동작했다.

는 뜻은 아닙니다.


20.1 TCP ACK와 Application ACK를 구분한다#

구조:

Application
↓
TCP
↓
Network
↓
TCP
↓
Application

TCP ACK:

Byte 전달 확인

Application ACK:

Command 수신·처리 결과

입니다.

따라서 TCP 기반 장비 Protocol에서도 Application Level ACK가 필요할 수 있습니다.


21장 ACK가 왔는데도 장비가 동작하지 않는 이유#

가능한 흐름:

Command 정상 수신
↓
ACK 전송
↓
안전 Sensor 확인
↓
조건 불충족
↓
Motor 미동작

이 경우 통신 자체는 정상입니다.

하지만 업무 결과는 실패입니다.

따라서 이후:

EXECUTION_FAILED

또는:

INTERLOCK_ACTIVE

같은 Event나 Status가 필요할 수 있습니다.


22장 응답을 못 받았을 때 STATUS 조회가 유용하다#

Command를 보냈습니다.

SEQ 42
OPEN_GATE

그런데 ACK가 없습니다.

즉시 동일한 OPEN을 반복하기보다 Protocol이 지원한다면:

STATUS

를 조회할 수 있습니다.

응답:

GATE = OPEN

이라면 최초 Command가 실제로 실행됐지만 ACK만 손실된 상황일 수 있습니다.


22.1 Command Retry보다 상태 확인이 안전한 경우#

특히 물리적 동작을 일으키는 Command:

OPEN

CLOSE

MOVE

PAY

RESET

REBOOT

등에서는 무조건 재전송하기보다 현재 상태를 먼저 확인하는 정책이 더 안전할 수 있습니다.

Protocol과 장비 특성에 맞춰 설계해야 합니다.


23장 Sequence Number는 얼마나 길어야 할까#

간단한 장비에서는:

1 Byte

Sequence를 사용할 수 있습니다.

범위:

0 ~ 255

입니다.

그러면:

254
255
0
1

처럼 Wrap-around가 발생합니다.

수신 측에서는 이 상황도 고려해야 합니다.


24장 Sequence Number만 보고 오래된 Packet을 판단하면 안 된다#

1 Byte Sequence는 언젠가 같은 번호가 다시 사용됩니다.

예:

SEQ 42

가 과거에도 있었고 현재에도 다시 나타날 수 있습니다.

따라서 중복 판단에는 상황에 따라:

Sequence Number

Timestamp

Device ID

Command

Session ID

같은 값을 조합할 수도 있습니다.


25장 Transaction ID를 사용하는 방법도 있다#

Sequence보다 더 명확한 요청 식별자가 필요하다면 Transaction ID를 사용할 수 있습니다.

예:

transaction_id:
8f72a341

Request:

TXID 8f72a341
OPEN_GATE

Response:

TXID 8f72a341
SUCCESS

이렇게 하면 요청과 응답을 명확하게 연결하기 쉽습니다.


26장 중복 Packet과 중복 Command는 구분해야 한다#

같은 Packet이 두 번 들어왔다고 하겠습니다.

SEQ 42 OPEN
SEQ 42 OPEN

이것은 Network Retry일 수 있습니다.

반면:

SEQ 42 OPEN
SEQ 43 OPEN

은 Application에서 같은 업무 Command를 두 번 생성한 것일 수도 있습니다.

따라서:

Duplicate Packet

과:

Duplicate Business Command

는 다른 문제입니다.


27장 로그에는 Sequence와 Command를 같이 남긴다#

좋은 Log:

14:10:00.100 TX
SEQ=42
CMD=OPEN_GATE

14:10:00.125 RX
SEQ=42
STATUS=ACK

14:10:02.410 RX
SEQ=42
STATUS=OPEN_COMPLETE

이렇게 남기면 하나의 Command가:

전송
↓
ACK
↓
물리 완료

까지 얼마나 걸렸는지 추적할 수 있습니다.


28장 Retry Log도 반드시 남긴다#

예:

14:20:10.000 TX
SEQ=51
CMD=STATUS

14:20:10.500 TIMEOUT
SEQ=51

14:20:10.700 RETRY #1
SEQ=51

14:20:10.725 RX ACK
SEQ=51

이런 기록은 다음 문제를 분석하는 데 유용합니다.

Network 지연

Device 처리 지연

Timeout 설정

간헐적 Packet Loss

29장 주차관제 Gate 제어 흐름을 다시 보자#

안전한 흐름을 단순화하면:

차량 감지
↓
권한 확인
↓
OPEN_GATE
SEQ 42
↓
ACK 42
↓
Gate 구동
↓
Open Sensor
↓
OPEN_COMPLETE 42

이렇게 통신 성공과 실제 동작 완료를 구분할 수 있습니다.


29.1 ACK 이후에도 실패할 수 있다#

예:

OPEN_GATE
↓
ACK
↓
Motor 시작
↓
Safety Sensor 감지
↓
동작 중단

최종 결과:

OPEN_FAILED

가 될 수 있습니다.

따라서 중앙 시스템에서는 ACK만으로 업무 상태를 완료 처리하지 않는 것이 중요합니다.


30장 안전 관련 Command는 상태 기계로 관리하는 것이 좋다#

예를 들어 Gate를 다음 상태로 관리할 수 있습니다.

CLOSED

OPENING

OPEN

CLOSING

ERROR

Command:

OPEN

을 받았을 때 현재 상태가:

OPEN

이면:

ALREADY_OPEN

을 반환할 수 있습니다.

현재 상태가:

OPENING

이면:

IN_PROGRESS

를 반환할 수도 있습니다.

이런 State Machine은 Duplicate Command의 위험을 줄이는 데 도움이 됩니다.


31장 NACK를 받았다고 무조건 재전송하지 않는다#

예:

NACK
ERROR = INVALID_COMMAND

인데 같은 Packet을 10번 다시 보낸다고 문제가 해결되지는 않습니다.

NACK 원인에 따라 처리 전략을 달리해야 합니다.

오류 대응 예시
CRC Error 재전송 고려
Busy 일정 시간 후 재시도
Invalid Command 재전송보다 Protocol 확인
Invalid Parameter Data 수정 필요
Permission Denied 인증·권한 확인
Safety Interlock 물리 상태 확인

32장 Timeout도 무조건 Retry로 처리하지 않는다#

Timeout에는 다양한 원인이 있습니다.

Packet Loss

장비 Offline

Address 오류

장비 처리 지연

Cable 장애

Response 손실

장비는 실행했지만 ACK만 손실

따라서 Command 성격에 따라:

Retry

STATUS 조회

Operator 확인

장비 Offline 처리

중 적절한 방법을 선택해야 합니다.


33장 ACK/NACK도 Protocol 보안 기능은 아니다#

공격자가 Protocol을 알고 있다면:

가짜 ACK

가짜 NACK

가짜 Sequence

를 만들 가능성도 있습니다.

따라서 신뢰할 수 없는 Network에서는:

Authentication

Authorization

Encryption

Integrity Protection

이 별도로 필요합니다.


34장 Sequence Number가 Replay Attack을 막아주지는 않는다#

공격자가 과거 Packet:

SEQ 42
OPEN_GATE

을 Capture했다고 하겠습니다.

장비가 단순히 Sequence만 확인한다면 상황에 따라 과거 Message를 다시 전송하는 Replay Attack을 충분히 막지 못할 수 있습니다.

보안이 필요한 환경에서는:

Nonce

Timestamp

Session ID

MAC / HMAC

Digital Signature

등을 활용할 수 있습니다.


35장 CRC와 Sequence도 목적이 다르다#

혼동하기 쉬운 부분입니다.

CRC
→ Packet이 손상됐는지 검사

Sequence Number
→ Packet 순서·중복·요청 관계 확인

ACK
→ 수신 또는 처리 상태 확인

Timeout
→ 응답을 얼마나 기다릴지 결정

Retry
→ 응답 실패 시 다시 전송

각각 해결하는 문제가 다릅니다.


36장 전체 Packet을 보면 역할이 더 명확하다#

가상의 Packet:

7E 01 2A 10 01 DATA CRC

Protocol이 다음처럼 정의됐다고 하겠습니다.

7E
Frame Start

01
Device Address

2A
Sequence Number 42

10
OPEN_GATE

01
Parameter

DATA
Additional Data

CRC
Integrity Check

응답:

7E 01 2A 90 00 CRC

이라면:

2A
→ 같은 Sequence

90
→ Response

00
→ Success

같은 방식으로 요청과 응답을 연결할 수 있습니다.


37장 REST API에서도 같은 문제가 존재한다#

장비 통신만의 문제가 아닙니다.

예:

POST /api/devices/gate-01/commands

Body:

{
  "requestId": "req-42",
  "command": "OPEN_GATE"
}

Server Response:

{
  "requestId": "req-42",
  "status": "accepted"
}

여기서도 accepted가 실제 Gate Open 완료라는 뜻은 아닐 수 있습니다.

나중에:

{
  "requestId": "req-42",
  "status": "completed"
}

Event를 별도로 받을 수도 있습니다.

핵심 원리는 Serial Device Protocol과 같습니다.


38장 ACK 방식별 차이#

방식 의미 특징
별도 ACK Frame 수신 확인을 별도 Packet으로 전달 상태 구분이 명확
Response 내부 Status 업무 Response와 함께 전달 구현 단순
Event 기반 완료 통지 실제 장비 동작 후 별도 Event 물리 상태 확인에 유리
TCP Transport ACK TCP Byte 전달 확인 Application 실행 여부와 별개

39장 장애가 생겼을 때 무엇을 확인할까#

Command는 보이는데 ACK가 없다#

확인:

Address

CRC

Device 상태

Driver Enable

Protocol Version

Timeout

ACK는 오는데 장비가 동작하지 않는다#

확인:

ACK 의미

Safety Interlock

Device State

Motor / Relay

Sensor

같은 동작이 두 번 발생한다#

확인:

Retry

Sequence

Duplicate 처리

Idempotency

Application Command 중복

40장 ACK가 늦게 도착하는 문제#

Server가:

SEQ 42

를 전송했습니다.

Timeout이 발생해:

Retry SEQ 42

를 보냈습니다.

그 직후 첫 번째 Packet의 ACK가 늦게 도착할 수 있습니다.

Delayed ACK 42

이 경우 Application이:

현재 Pending Request와
어떤 관계인지

정확하게 판단해야 합니다.

Sequence Number와 Request State가 필요한 이유입니다.


41장 오래된 응답도 처리하면 안 된다#

예:

현재 Request
SEQ 50

늦게 도착한 Response
SEQ 42

이라면 오래된 Response를 현재 Command의 성공으로 처리해서는 안 됩니다.

Protocol Handler는:

Pending Request

Expected Sequence

Timeout 상태

를 관리해야 합니다.


42장 Restart 후 Sequence 초기화도 고려한다#

Device가 재부팅되면서 Sequence를:

0

으로 초기화할 수 있습니다.

Server와 Device가 서로 다른 Sequence 상태를 가지고 있다면 중복 판단이 꼬일 수 있습니다.

Protocol에 따라:

Session Reset

Handshake

Device Boot ID

Sequence Reset

같은 정책이 필요할 수 있습니다.


43장 현장 로그에서 찾아야 할 패턴#

다음과 같은 흐름을 찾습니다.

TX SEQ 10

TIMEOUT

TX SEQ 10 RETRY

RX ACK SEQ 10

또는:

TX SEQ 10

RX ACK SEQ 10

TX SEQ 11

RX ACK SEQ 10

두 번째는 오래된 ACK가 늦게 도착한 상황일 수 있습니다.

Timestamp와 Sequence를 같이 보면 이런 현상을 찾기 쉬워집니다.


44장 현장 장애 진단 순서#

1. Command가 실제로 전송됐는가?
↓
2. Sequence Number는 무엇인가?
↓
3. 장비가 Packet을 수신했는가?
↓
4. ACK 또는 Response가 발생했는가?
↓
5. Response Sequence가 맞는가?
↓
6. Timeout은 적절한가?
↓
7. Retry가 발생했는가?
↓
8. Duplicate 처리됐는가?
↓
9. 실제 장비 상태가 변했는가?
↓
10. 완료 Event 또는 Sensor가 확인됐는가?

이 순서대로 보면 통신 성공과 실제 업무 성공을 분리해서 판단할 수 있습니다.


45장 흔히 하는 잘못된 판단#

45.1 ACK가 왔으니 장비가 실제로 동작했다#

Protocol이 ACK를 무엇으로 정의했는지 확인해야 합니다.

45.2 Timeout이면 장비가 Command를 받지 못했다#

Command는 처리됐지만 Response만 손실됐을 수도 있습니다.

45.3 응답이 없으면 같은 Command를 계속 재전송한다#

물리적인 제어 Command에서는 위험할 수 있습니다.

45.4 Sequence Number만 있으면 중복 문제가 모두 해결된다#

Wrap-around, Restart, 오래된 Packet 등을 고려해야 합니다.

45.5 TCP를 사용하면 Application ACK가 필요 없다#

TCP ACK는 Application Command 실행 완료를 보장하지 않습니다.

45.6 ACK/NACK와 Sequence Number가 있으면 보안도 해결된다#

아닙니다. 인증·암호화·Replay Protection은 별도로 필요합니다.


46장 장비 통신 설계 체크리스트#

□ ACK가 정확히 무엇을 의미하는가?

□ NACK에 Error Code가 존재하는가?

□ Request와 Response를 어떤 값으로 연결하는가?

□ Sequence Number 또는 Transaction ID가 있는가?

□ Sequence가 Wrap-around되면 어떻게 처리하는가?

□ Timeout 값은 어떻게 결정했는가?

□ 최대 Retry 횟수는 몇 회인가?

□ NACK 유형별 Retry 정책이 다른가?

□ Duplicate Packet을 어떻게 처리하는가?

□ Command가 Idempotent한가?

□ ACK와 실행 완료를 구분하는가?

□ 물리 Sensor로 실제 상태를 확인할 수 있는가?

□ Restart 후 Sequence 상태는 어떻게 초기화되는가?

□ 오래된 Response를 버리는가?

□ Log에 Timestamp·Sequence·Direction이 남는가?

47장 자기 점검#

47.1 ACK는 무엇을 의미하는가#

상대가 Message를 정상적으로 수신하거나 처리했다는 응답이지만 정확한 의미는 Protocol 정의에 따라 다릅니다.

47.2 NACK를 받으면 무조건 다시 보내야 하는가#

아닙니다.

NACK의 원인이 CRC Error인지 Invalid Command인지에 따라 대응 방법이 달라집니다.

47.3 Sequence Number가 필요한 이유는 무엇인가#

Request와 Response를 연결하고 Packet의 중복·누락·재전송을 구분하는 데 도움을 줍니다.

47.4 Timeout이 발생하면 Command 실행도 실패한 것인가#

반드시 그렇지는 않습니다.

Command는 실행됐지만 Response만 손실됐을 수도 있습니다.

47.5 ACK와 실제 장비 상태를 왜 구분해야 하는가#

Packet 수신 성공과 Motor·Relay·Gate 같은 물리 장치의 동작 완료는 서로 다른 사건이기 때문입니다.


48장 이 글을 마치며#

장비 통신에서 가장 중요한 질문은:

Packet을 보냈는가?

에서 끝나지 않습니다.

다음과 같이 이어져야 합니다.

Packet을 보냈는가?
↓
장비가 받았는가?
↓
정상적으로 해석했는가?
↓
Command를 실행했는가?
↓
실제 물리 상태가 변했는가?

ACK, NACK, Sequence Number, Timeout과 Retry는 이 과정의 일부를 확인하는 수단입니다.

전체 구조를 정리하면:

Command
↓
Sequence Number
↓
전송
↓
ACK / NACK
↓
Timeout 판단
↓
Retry 또는 상태 조회
↓
중복 검증
↓
실행 상태
↓
물리 상태 확인

으로 이어집니다.

특히 다음 다섯 가지를 기억하면 됩니다.

ACK는 통신 또는 처리 상태를 알려주는 응답이며 실제 장비 동작 완료를 의미하는지는 Protocol 정의를 확인해야 합니다.

NACK는 단순 실패 신호가 아니라 실패 이유에 따라 재전송 여부를 결정해야 하는 정보입니다.

Sequence Number는 Request와 Response를 연결하고 Duplicate Packet을 구분하는 데 사용됩니다.

Timeout이 발생했다고 Command가 실행되지 않았다고 단정할 수 없으므로 물리 제어에서는 무조건적인 재전송을 피해야 합니다.

통신 성공과 실제 업무 완료는 별개의 상태로 관리하는 것이 안전하고 장애 분석에도 유리합니다.

결국 신뢰할 수 있는 장비 통신은 단순히:

보냈다.
받았다.

를 확인하는 것이 아닙니다.

어떤 요청에 대한 어떤 응답인지 확인하고, 중복을 걸러내며, 마지막에는 실제 장비의 상태가 의도한 상태로 바뀌었는지까지 확인하는 것이 핵심입니다.

이 페이지의 목차