tags: DoIP, Automotive Ethernet, UDS, 차량용 이더넷, 진단 통신, TCP Framing, DevBJ
요즘 차량 전장(Automotive Electronics) 분야나 임베디드 통신 쪽을 다루다 보면 어느 순간 'DoIP(Diagnostic over Internet Protocol)'라는 녀석과 훅 부딪히게 됩니다. 과거에는 CAN 통신 하나만 꽉 잡고 있어도 진단 통신 구현에 큰 무리가 없었지만, 이제는 상황이 완전히 달라졌죠.
처음 DoIP를 접하면 *"아, 그냥 랜선 꽂고 이더넷으로 진단하는 거겠지 뭐~"* 하고 가볍게 생각하기 쉽습니다. 하지만 실무에 들어가서 직접 패킷을 까보고 통신을 붙여보면? 기존 CAN 환경에서 흐르던 진단 메시지를 Ethernet/IP 환경에서 다루는 완전히 다른 패러다임 때문에 머리가 멍해지는 순간이 옵니다. (제가 며칠 밤을 새우며 삽질했던 기억이 나네요... 😅)
오늘은 DoIP 마스터 가이드의 첫 시간으로, 왜 우리가 익숙했던 CAN을 넘어 DoIP를 맞이하게 되었는지, 그리고 실무자가 반드시 알아야 할 패킷의 뼈대(Generic Header)와 개발자들을 멘붕에 빠뜨리는 TCP 프레이밍(Framing)에 대해 아주 쉽고 친근하게 파헤쳐 보겠습니다.
📌 [DoIP 마스터 가이드 시리즈 목차]
- ▶ [DoIP 마스터 가이드 1편] 왜 CAN 대신 이더넷일까? (탄생 배경과 패킷 구조, TCP 프레이밍의 함정)
- 👉 [DoIP 마스터 가이드 2편] 차량은 어떻게 찾고, 진단 길은 어떻게 뚫을까? (Vehicle Discovery & Routing Activation)
- 👉 [DoIP 마스터 가이드 3편] 본격적인 진단 시작! UDS 페이로드와 세션 유지의 비밀 (SA/TA & Tester Present)
- 👉 [DoIP 마스터 가이드 4편] 혈압 오르는 NRC 완벽 분석! 실전 트러블슈팅 가이드 (0x13, 0x22, 0x31, 0x78 등)
- 👉 [DoIP 마스터 가이드 5편] 실무 끝판왕! 펌웨어 전송과 다중 ECU 게이트웨이 라우팅 완벽 해부 (完)
1. 잘 쓰던 CAN 놔두고, 왜 굳이 이더넷과 DoIP인가요?
가장 먼저 드는 의문은 이것일 겁니다. *"CAN 통신도 충분히 훌륭한데, 왜 굳이 복잡하게 IP 기반 통신을 차에 집어넣은 걸까?"*
이유는 단순합니다. 요즘 차들이 다뤄야 할 데이터의 양과 속도가 미쳐 날뛰기 때문입니다. 기존 CAN(최대 1Mbps)이나 CAN-FD(최대 8Mbps)로는 도저히 감당이 안 되는 시대가 온 거죠.
- OTA (Over-The-Air) 업데이트의 일상화: 스마트폰처럼 차량 소프트웨어를 무선으로 슉슉 업데이트해야 합니다. 수십~수백 MB에 달하는 펌웨어를 CAN으로 보낸다? 아마 업데이트 한 번 하려다 차박을 해야 할지도 모릅니다. 대용량 데이터를 고속으로 쏘기 위한 '넓은 고속도로'가 필수적이게 되었습니다.
- 커넥티드 카 (Connected Car) 생태계: 차량 내외부가 인터넷으로 연결되면서, 우리에게 너무나도 익숙한 IT 표준 기술인 TCP/IP 스택을 그대로 활용하는 것이 비용이나 확장성 면에서 압도적으로 유리해졌습니다.
단, 여기서 아주 중요한 포인트 하나 짚고 넘어갈게요!
DoIP가 진단 전용 프로토콜을 백지부터 새로 만든 게 아닙니다.
DoIP는 기존 우리가 알던 차량 진단 메시지(UDS)를 IP 네트워크상에서 잃어버리지 않고 잘 전달하기 위해 안전하게 포장하는 '택배 박스(Encapsulation)'라고 생각하시면 딱 맞습니다.
2. DoIP 패킷 구조: 8바이트 Generic Header의 비밀
DoIP 패킷을 Wireshark 같은 툴로 캡처해서 처음 열어보면 헥사(Hex) 값들이 어지럽게 널려 있어서 현기증이 날 수 있습니다. 하지만 쫄 필요 전혀 없어요! 규칙은 아주 단순합니다.
DoIP는 무조건 맨 앞에 '8바이트의 공통 헤더(Generic Header)'가 붙고, 그 뒤에 메시지 목적에 따라 내용물(Payload)이 쏙 들어가는 구조입니다. 실무에서 패킷을 까볼 때는 묻지도 따지지도 말고 이 8바이트부터 읽어내는 감각이 필요합니다.
[ DoIP Generic Header - 총 8 bytes ]
+------------------------+
| Protocol Version | 1 byte
+------------------------+
| Inverse Version | 1 byte
+------------------------+
| Payload Type | 2 bytes
+------------------------+
| Payload Length | 4 bytes
+------------------------+
[ Payload (내용물) | N bytes ]
- Protocol Version / Inverse Version: 현재 쓰고 있는 DoIP 버전을 나타냅니다. 재미있는 건 버전 값의 반전 값(Inverse, 0xFF에서 뺀 값)을 바로 뒤에 하나 더 붙인다는 점이에요. 헤더 데이터가 네트워크를 타고 오면서 깨지지 않았는지 빠르게 1차 검증(Sanity Check)을 하는 귀여운 꼼수입니다.
- Payload Type (★진짜 중요!): 뒤에 이어지는 데이터가 도대체 어떤 목적인지 알려주는 핵심 필드입니다. 차를 찾는 건지(Vehicle Identification), 진단 길을 뚫는 건지(Routing Activation), 진짜 진단 메시지(Diagnostic Message)인지 여기서 다 판가름 납니다.
- Payload Length (★이것도 핵심!): 뒤따라오는 페이로드의 '정확한 바이트 길이'를 알려줍니다.
결국 패킷 분석의 정석은 이렇습니다.
"8바이트 읽어서 이상 없는지 확인 ➡️ Payload Type으로 분기 타기 ➡️ Length만큼 정확히 읽어서 파싱하기"
3. 실무자를 멘붕에 빠뜨리는 함정: TCP 스트림 프레이밍(Stream Framing)
DoIP를 처음 직접 구현(Parsing)해 볼 때, 거의 99%의 개발자가 빠지는 치명적인 함정이 하나 있습니다.
*"TCP 소켓의
recv()함수를 딱 호출하면, 친절하게 DoIP 패킷 1개를 완벽하게 돌려주겠지?"*
절대 아닙니다.
UDP와 달리 TCP는 '스트림(Stream)' 기반입니다. 물줄기처럼 데이터의 경계 없이 쭈욱 흘러옵니다. 그렇기 때문에 실무에서는 이런 일들이 미친 듯이 일어납니다.
- 메시지가 쪼개져서 옴: 헤더 3바이트 먼저 오고, 조금 있다가 5바이트 오고...
- 메시지 2개가 하나로 떡져서 옴: 패킷 A와 패킷 B가 한 번의
recv()에 뭉쳐서 들어옴.
단순히 recv(4096)을 호출해서 나온 결과 뭉치를 그대로 파싱하려고 하면? 어쩔 때는 잘 되다가 트래픽이 몰리면 갑자기 'Payload Length Mismatch' 에러를 뿜으며 장렬하게 뻗어버립니다. (이거 찾느라 진짜 고생 많이 하거든요 🥲)
💡 해결책: 버퍼에 담고 '프레이밍(Framing)' 하기!
우리는 직접 메시지 경계를 잘라주는 칼잡이가 되어야 합니다.
- 소켓에서 읽은 데이터를 무조건
수신 버퍼(rx_buf)에 계속 이어 붙여서 누적합니다. - 버퍼에 8바이트 이상이 모였을 때만 헤더를 살짝 읽어서
Payload Length를 확인합니다. 전체 길이 (8바이트 헤더 + Payload Length)만큼 버퍼에 데이터가 모두 찰 때까지 얌전히 기다립니다.- 데이터가 다 모이면 딱 그 길이만큼만 썰어서(Framing) DoIP 메시지 1개로 처리하고, 버퍼에서 날려줍니다.
이 TCP 프레이밍(Stream Framing) 로직을 초반에 탄탄하게 짜두지 않으면, 나중에 대용량 펌웨어(Firmware Transfer)를 전송할 때 통신이 무작위로 툭툭 끊기는 대참사를 겪게 됩니다. (펌웨어 전송 최적화에 대한 이야기는 [👉 5편]에서 아주 깊게 다룰 예정입니다!)
📝 1편 마무리: 다음 단계로 넘어갈 준비!
지금까지 왜 자동차에 이더넷과 DoIP가 들어오게 되었는지, 그리고 뼈대가 되는 공통 헤더 구조와 TCP 프레이밍의 중요성에 대해 가볍게 워밍업을 해보았습니다.
CAN 진단의 '버스(Bus)'에 냅다 던지던 마인드에서 벗어나, IP 네트워크 기반의 '정교한 연결(Connection)과 조립' 관점으로 생각을 전환하셨다면 오늘 목표는 200% 달성하신 겁니다! 👏
기본적인 네트워크 뼈대를 이해했으니, 이제 진단기(Tester)가 네트워크 상에 꽁꽁 숨어있는 차량(ECU)을 찾아내고(Discovery), 진단 통신을 위한 진짜 문을 활짝 여는(Routing Activation) 흥미진진한 과정을 알아볼 차례입니다.
👉 [다음 글 보기: DoIP 마스터 가이드 2편 - 차량 네트워크 연결 및 식별 메커니즘 파헤치기]
읽으시면서 헷갈리거나 실무에서 막히는 부분이 있다면 언제든 편하게 댓글 남겨주세요. 같이 고민해 보겠습니다. 지금까지 DevBJ였습니다!
'IT > 자동차' 카테고리의 다른 글
| [DoIP 마스터 가이드 3편] 본격적인 진단 시작! UDS 페이로드와 세션 유지의 비밀 (SA/TA & Tester Present) (0) | 2026.08.18 |
|---|---|
| [DoIP 마스터 가이드 2편] 차량은 어떻게 찾고, 진단 길은 어떻게 뚫을까? (Vehicle Discovery & Routing Activation) (0) | 2026.08.18 |
| DTC와 Status Byte 완전 정리 (0) | 2026.03.24 |
| FEE - Flash EEPROM Emulation 왜 쓸까? (0) | 2026.02.04 |
| 프로비저닝 - 왜 이런 용어를 쓰는 걸까? (0) | 2026.01.15 |
