제3부 미들웨어: DDS·RTPS·RMW
3.2 RTPS 와이어 프로토콜
3.2.1 이 장에서 배우는 것 / 선수 지식
RTPS(Real-Time Publish-Subscribe Protocol)는 DDS가 실제로 네트워크에 내보내는 바이트의 규칙이다. 이 층을 아는 것이 왜 실무에 필요한가 — 세 가지 이유다.
- 방화벽·컨테이너 설정에 포트 번호가 필요하다. 그 번호는 도메인 ID에서 계산되며, 계산식을 모르면 "일단 다 열어" 말고는 방법이 없다.
- ROS 2 도구로 답할 수 없는 질문(재전송이 일어나는가, 디스커버리가 얼마나 수행되는가)의 답이 여기 있다.
- 패킷 캡처를 읽을 수 있게 된다. 네트워크 문제 진단에서 이것이 최종 심판이다.
배우는 것:
- RTPS의 위치와 목표 — 왜 별도 프로토콜이 필요했나.
- GUID — 엔티티를 전역으로 식별하는 방법.
- 메시지 구조 — 헤더 + 서브메시지, 주요 서브메시지의 역할.
- 신뢰성 메커니즘 — HEARTBEAT·ACKNACK·GAP의 상호작용.
- 조각화 — 큰 메시지가 MTU를 넘을 때.
- 포트 계산식 — 방화벽 규칙을 정확히 쓰는 법.
- 패킷 캡처 읽기 — Wireshark로 무엇을 확인하는가.
- 패킷으로 대조한 결과(3.2.12) — 포트 계산식 확인, 멀티캐스트 그룹의 함의, 조각 크기의 경로 의존.
선수 지식: 3.1(DDS 개념), 1.5(QoS), 1.4(발행 경로). 네트워크 기초(UDP·멀티캐스트·MTU)를 안다고 가정한다.
정직: RTPS 구조·포트 계산식은 OMG RTPS 명세(2.2 이상)에 근거한다. 기본 파라미터 값(PB·DG·PG·d0~d3)은 명세의 기본값이며, 벤더가 설정으로 바꿀 수 있다. 아래 계산 결과는 기본값 기준이고 이 환경에서 캡처로 검증하지 않았다(목차 3). 자신의 시스템에서 실제 사용 포트는
ss -ulnp로 확인하는 것이 정본이다. 다만 포트 계산식과 조각 크기는 패킷 캡처로 대조했다(실행 확인 — 3.2.12).
3.2.2 RTPS의 위치와 목표
RTPS가 별도로 표준화된 이유: DCPS는 API를 정할 뿐 바이트를 정하지 않는다. 서로 다른 벤더의 DDS가 통신하려면 바이트 수준 합의가 필요했고, 그것이 RTPS다.
설계 목표:
| 목표 | 결과 |
|---|---|
| 비연결(connectionless) 위에서 신뢰성 | UDP 위에 자체 재전송 — TCP 연결 관리 비용 회피 |
| 실시간성 | 오래된 데이터를 버릴 수 있다(TCP는 못 한다 — 1.5.2) |
| 멀티캐스트 활용 | 1:N 전송을 네트워크가 복제 |
| 플러그앤플레이 | 중앙 설정 없이 서로를 발견(3.3) |
| 확장성 | 벤더 확장 서브메시지 허용 |
"UDP 위에 신뢰성"이 핵심이다. TCP를 쓰지 않는 이유는 1.5.2에서 본 것 — TCP는 순서와 완전성을 강제해서 오래된 데이터가 최신 데이터를 막는다. RTPS는 신뢰성을 QoS로 선택하게 하고, 신뢰성을 켜도 히스토리에서 축출된 것은 포기한다(1.5.3.2).
3.2.3 GUID — 전역 식별자
RTPS의 모든 엔티티는 16바이트 GUID로 식별된다.
$$\mathrm{GUID}\ (16\ \mathrm{bytes}) = \mathrm{GuidPrefix}\ (12\ \mathrm{bytes}) + \mathrm{EntityId}\ (4\ \mathrm{bytes})$$
| 부분 | 내용 |
|---|---|
| GuidPrefix | 참가자를 식별. 벤더 ID + 호스트·프로세스 기반 값(구현마다 생성 방식이 다름) |
| EntityId | 참가자 안에서의 엔티티. 3바이트 키 + 1바이트 종류 |
EntityId의 종류 바이트가 그 엔티티가 무엇인지 알려준다 — 쓰기/읽기, 키 있음/없음, 사용자/내장(built-in).
내장 엔티티는 고정된 EntityId를 갖는다. 디스커버리용 엔티티(SPDP·SEDP 리더·라이터)가 그것이며, 고정이기 때문에 서로를 미리 알고 통신을 시작할 수 있다(3.3).
실무적 의미:
| 사실 | 결과 |
|---|---|
| GuidPrefix가 참가자마다 다르다 | 캡처에서 어느 프로세스의 패킷인지 구분 가능 |
| 같은 GuidPrefix = 같은 참가자 | 노드↔참가자 매핑을 캡처로 확인할 수 있다(2.1.4) |
| 벤더 ID가 들어간다 | 캡처에서 상대 벤더를 알 수 있다 |
| 내장 EntityId는 고정 | 디스커버리 트래픽을 필터링해 구분 가능 |
ros2 topic info -v가 보여주는 GID가 이 GUID에 대응한다(0.7.5) — CLI 출력과 패킷 캡처를 연결하는 고리다.
3.2.4 메시지 구조 — 헤더와 서브메시지
하나의 UDP 데이터그램에 여러 서브메시지가 들어간다.
헤더에 GuidPrefix가 있으므로, 뒤따르는 서브메시지들은 EntityId만 담으면 된다 — 대역 절약을 위한 설계다.
주요 서브메시지:
| 서브메시지 | 방향 | 역할 |
|---|---|---|
DATA | Writer → Reader | 실제 데이터 샘플 |
DATA_FRAG | Writer → Reader | 조각난 큰 샘플(3.2.6) |
HEARTBEAT | Writer → Reader | "내게 시퀀스 N~M이 있다" |
HEARTBEAT_FRAG | Writer → Reader | 조각 단위 하트비트 |
ACKNACK | Reader → Writer | "N까지 받았다 / K가 없다" |
NACK_FRAG | Reader → Writer | 조각 단위 재요청 |
GAP | Writer → Reader | "이 시퀀스들은 안 온다"(필터링·만료) |
INFO_TS | — | 뒤따르는 서브메시지의 타임스탬프 |
INFO_DST | — | 목적지 GuidPrefix 변경 |
INFO_SRC | — | 출처 정보 변경 |
INFO_REPLY | — | 응답 주소 |
PAD | — | 정렬용 채움 |
GAP이 중요한데 자주 간과된다. 발행자가 어떤 시퀀스를 보내지 않기로 결정했을 때(lifespan 만료 — 1.5.3.5, 또는 내용 필터링) 이를 알려 준다. 이것이 없으면 구독자는 없는 샘플을 영원히 기다리며 재전송을 요청한다.
시퀀스 번호: 각 Writer는 자기 샘플에 1부터 증가하는 시퀀스 번호를 붙인다. 신뢰성의 전부가 이 번호 위에 세워진다.
3.2.5 신뢰성 메커니즘 — HEARTBEAT와 ACKNACK
동작 요약:
- Writer가
DATA를 보낸다(멀티캐스트 또는 유니캐스트). - Writer가 주기적으로
HEARTBEAT를 보내 "내게 seq 1~N이 있다"고 알린다. - Reader가
ACKNACK으로 "M까지 받았고 K가 빠졌다"고 답한다. - Writer가 빠진 것을 재전송한다.
BEST_EFFORT에서는 이 전부가 없다. DATA만 보내고 끝이다 — 그래서 오버헤드가 작고 지연이 예측 가능하다.
튜닝 지점들(벤더 XML — 3.7·3.8):
| 파라미터 | 영향 |
|---|---|
| HEARTBEAT 주기 | 짧으면 유실 복구가 빠르지만 트래픽 증가 |
| ACKNACK 응답 지연 | 짧으면 반응 빠름, 길면 여러 응답을 묶어 트래픽 절감 |
| NACK 억제(suppression) | 멀티캐스트에서 여러 Reader가 동시에 NACK을 보내는 폭주 방지 |
| 재전송 정책 | 유니캐스트 vs 멀티캐스트 재전송 |
무선에서 문제가 되는 지점이 명확히 보인다(1.6.5). 유실률이 높으면 ACKNACK과 재전송이 늘고, 그 트래픽이 다시 유실률을 높인다. HEARTBEAT 주기를 늘리고 재전송을 억제하는 것이 무선 튜닝의 핵심이며, 근본적으로는 BEST_EFFORT로 내리는 것이 맞다.
정직: 위 파라미터의 정확한 이름과 기본값은 벤더마다 완전히 다르다. Fast DDS와 Cyclone DDS는 설정 문법도 개념 구성도 다르다(3.7·3.8). 여기서는 어떤 종류의 손잡이가 있는지만 세운다.
3.2.6 포트 계산식 — 방화벽 설정의 근거
이 절이 이 장에서 가장 실용적이다. RTPS 포트는 도메인 ID와 참가자 ID에서 계산된다.
기본 파라미터(명세 기본값):
| 기호 | 이름 | 기본값 |
|---|---|---|
| $PB$ | Port Base | 7400 |
| $DG$ | Domain ID Gain | 250 |
| $PG$ | Participant ID Gain | 2 |
| $d_0$ | 멀티캐스트 디스커버리 오프셋 | 0 |
| $d_1$ | 유니캐스트 디스커버리 오프셋 | 10 |
| $d_2$ | 멀티캐스트 사용자 데이터 오프셋 | 1 |
| $d_3$ | 유니캐스트 사용자 데이터 오프셋 | 11 |
계산식 ($D$ = 도메인 ID, $P$ = 참가자 ID):
$$ \begin{aligned} \text{멀티캐스트 디스커버리} &= PB + DG \cdot D + d_0 \\ \text{유니캐스트 디스커버리} &= PB + DG \cdot D + d_1 + PG \cdot P \\ \text{멀티캐스트 사용자 데이터} &= PB + DG \cdot D + d_2 \\ \text{유니캐스트 사용자 데이터} &= PB + DG \cdot D + d_3 + PG \cdot P \end{aligned} $$
도메인 0의 예:
| 용도 | 계산 | 포트 |
|---|---|---|
| 멀티캐스트 디스커버리 | $7400 + 0 + 0$ | 7400 |
| 유니캐스트 디스커버리(참가자 0) | $7400 + 0 + 10 + 0$ | 7410 |
| 유니캐스트 디스커버리(참가자 1) | $7400 + 0 + 10 + 2$ | 7412 |
| 멀티캐스트 사용자 데이터 | $7400 + 0 + 1$ | 7401 |
| 유니캐스트 사용자 데이터(참가자 0) | $7400 + 0 + 11 + 0$ | 7411 |
도메인 1이면 전부 250씩 증가한다 — 7650, 7660, 7651, 7661…
여기서 나오는 실무 결론들:
① 방화벽 규칙을 정확히 쓸 수 있다.
# 도메인 0, 참가자 0~10을 허용한다면
# 디스커버리: 7400(멀티캐스트), 7410~7430(유니캐스트)
# 사용자 데이터: 7401(멀티캐스트), 7411~7431(유니캐스트)
sudo ufw allow 7400:7440/udp
sudo ufw allow proto udp to 239.255.0.1 # 기본 디스커버리 멀티캐스트 주소
② 도메인 ID 상한이 왜 있는지 설명된다. $D$가 커지면 $7400 + 250D$가 65535를 넘거나, 다른 서비스가 쓰는 포트 대역을 침범한다.
$$D_{\max} \approx \frac{65535 - 7400}{250} \approx 232$$
그러나 리눅스의 임시 포트(ephemeral port) 범위와 충돌할 수 있어 실무 권장은 더 낮다(대략 0~101)(확인 필요: 배포판·OS 설정 의존).
sysctl net.ipv4.ip_local_port_range # 이 범위와 겹치면 충돌 가능
③ 참가자 ID가 포트를 소비한다. 한 호스트에서 참가자가 많으면(노드마다 참가자를 만드는 구현 — 2.1.4) 포트를 그만큼 쓴다. 참가자 ID는 호스트 안에서 순차 할당되며, 한계에 도달하면 새 참가자가 생성되지 않을 수 있다.
④ 실제 포트는 확인할 수 있다.
ss -ulnp | grep -E '74[0-9][0-9]|76[0-9][0-9]'
# 또는 특정 프로세스
ss -ulnp | grep $(pgrep -f my_node)
함정: 벤더가 기본 파라미터를 바꿀 수 있고, 사용자 정의 포트 설정도 가능하다. 위 계산은 출발점이며, 정답은
ss로 확인한 값이다. 특히 Discovery Server(3.4)나 TCP 전송을 쓰면 완전히 다른 포트를 쓴다.
멀티캐스트 주소: 기본 디스커버리 멀티캐스트 주소는 239.255.0.1이며(확인 필요: 벤더·설정 의존), 이 주소로의 트래픽이 막히면 디스커버리가 실패한다(3.9).
3.2.7 조각화 — 큰 메시지가 MTU를 넘을 때
이더넷 MTU는 보통 1500바이트다. 6 MB 크기의 이미지(1.3.4)는 당연히 안 들어간다.
두 가지 조각화가 존재한다:
| 층 | 방식 | 성질 |
|---|---|---|
| IP 조각화 | 커널이 IP 패킷을 단편화한다 | 한 조각만 잃어도 전체 재조립 실패 |
RTPS 조각화(DATA_FRAG) | RTPS가 샘플을 분할한다 | 잃은 조각만 재전송 가능(NACK_FRAG) |
RTPS 조각화가 훨씬 낫다. 6 MB를 IP 조각화로 보내면 4000여 조각이 되고, 그중 하나만 잃어도 6 MB 전체가 무효가 된다. 유실률이 조금만 있어도 사실상 전달이 불가능해진다.
$$P_{\text{성공}} = (1 - p)^{N_{\text{조각}}}$$
유실률 $p = 0.1\%$, 조각 4000개면 $P_{\text{성공}} \approx 0.999^{4000} \approx 1.8\%$ — 거의 전달되지 않는다.
함정: 대용량 토픽이 "가끔 오다 말다" 하는 현상의 전형적 원인이 이것이다. 특히 무선에서 두드러진다. 해결은 ① RTPS 조각화가 동작하도록 벤더 설정 확인(대개 기본 활성), ② 소켓 버퍼 확대(1.4.4), ③ 애초에 큰 메시지를 보내지 않기(압축·다운샘플링 — 7.2·7.8).
설정 지점(벤더별로 다름 — 3.7·3.8):
| 항목 | 의미 |
|---|---|
| 최대 메시지 크기 | 이보다 크면 조각화 |
| 조각 크기 | MTU에 맞춰야 IP 조각화를 피한다 |
| 흐름 제어(flow controller) | 조각을 한꺼번에 쏟지 않고 속도 제한 |
흐름 제어가 특히 중요하다. 6 MB를 조각 4000개로 분할하 한꺼번에 보내면 스위치·수신 측 버퍼가 넘쳐 대량 유실이 난다. 초당 전송량을 제한하면 오히려 전체 처리량이 높아지는 역설이 흔하다.
3.2.8 패킷 캡처 읽기
# RTPS 트래픽만 캡처
sudo tcpdump -i any -w rtps.pcap 'udp portrange 7400-7700'
# 인터페이스 지정 (멀티캐스트는 인터페이스 선택이 중요 — 3.9)
sudo tcpdump -i eth0 -w rtps.pcap 'udp portrange 7400-7700'
Wireshark 필터 예:
| 목적 | 필터 |
|---|---|
| RTPS 전체 | rtps |
| 디스커버리만 | rtps.sm.id == 0x15 && udp.port == 7400(대략)(확인 필요) |
| 데이터 서브메시지 | rtps.sm.id == 0x15 |
| 하트비트 | rtps.sm.id == 0x07 |
| ACKNACK | rtps.sm.id == 0x06 |
| 특정 참가자 | rtps.guidPrefix == … |
정직: 서브메시지 ID 값과 Wireshark 필드 이름은 버전에 따라 다를 수 있다
(확인 필요). 실무에서는 필터를 외우기보다 패킷을 하나 클릭해 트리에서 필드 이름을 확인하고 "필터로 적용" 하는 방식이 확실하다.
무엇을 확인하는가:
특히 유용한 두 가지 측정:
① 디스커버리 트래픽 비율 — 전체 패킷 중 디스커버리(내장 엔티티) 패킷의 비율. 이것이 높으면 그래프가 너무 크거나 참가자가 너무 많다(3.3·3.4).
② 재전송 비율 — ACKNACK 후 재전송되는 DATA 비율. 높으면 링크 품질 문제이며, QoS를 BEST_EFFORT로 내리거나 전송량을 줄여야 한다(1.6.5).
둘 다 ROS 2 CLI로는 절대 알 수 없는 정보다(3.1.10).
3.2.9 전송 계층 선택
RTPS는 전송에 독립적이며, 벤더가 여러 전송을 제공한다.
| 전송 | 특징 | 언제 |
|---|---|---|
| UDPv4 | 기본. 멀티캐스트 가능 | 일반 LAN |
| UDPv6 | IPv6 | IPv6 환경 |
| TCPv4 | 연결 지향. NAT·방화벽 통과 유리 | WAN·클라우드·제한된 네트워크 |
| 공유메모리(SHM) | 같은 호스트 | 프로세스 간 고속(2.7) |
TCP 전송이 유용한 상황:
- 방화벽이 UDP를 막지만 TCP는 허용하는 경우.
- NAT 뒤에 있는 경우.
- WAN 구간(패킷 유실이 많고 멀티캐스트 불가).
대가: 연결 관리 오버헤드, 멀티캐스트 불가(N개 구독자면 N번 전송), head-of-line 블로킹 재발(1.5.2의 문제가 되돌아온다).
견해: TCP 전송은 "UDP가 불가능한 환경에서의 탈출구"이지 성능 개선책이 아니다. WAN·클라우드 연결이 목적이라면 zenoh(3.10)나 애플리케이션 레벨 브리지가 더 적합한 경우가 많다. TCP DDS는 "기존 구조를 그대로 두고 네트워크 제약만 우회"할 때 쓴다.
설정은 벤더 XML로 한다 — Fast DDS는 transport descriptor(3.7), Cyclone은 별도 설정(3.8).
3.2.12 패킷을 캡처해 계산식을 대조했다 — 실측
3.2.6은 "이 절이 이 장에서 가장 실용적이다"라고 적어 두었다. 그 계산식을 tcpdump로 대조했다(실행 확인, Jazzy, rmw_fastrtps_cpp, --cap-add NET_RAW).
tcpdump -i any -nn -l "udp and portrange 7000-12000"
3.2.12.1 계산식이 정확히 맞는다
ros2 run demo_nodes_cpp talker를 도메인만 바꿔 실행하고 목적지 포트를 셌다.
| 도메인 $D$ | $PB + DG \cdot D$ | 관측된 멀티캐스트 목적지 |
|---|---|---|
| 0 | 7400 | 239.255.0.1:7400 |
| 1 | 7650 | 239.255.0.1:7650 |
| 7 | 9150 | 239.255.0.1:9150 |
| 33 | 15650 | 239.255.0.1:15650 |
참가자 게인까지 확인했다. 도메인 33에서 talker와 listener를 함께 실행하니 유니캐스트 목적지가 이렇게 나왔다.
| 용도 | 계산 | 관측 |
|---|---|---|
| 유니캐스트 디스커버리, 참가자 0 | $15650 + 10 + 2\cdot0$ | 15660 |
| 유니캐스트 디스커버리, 참가자 1 | $15650 + 10 + 2\cdot1$ | 15662 |
$PB + DG \cdot D + d_1 + PG \cdot P$ 가 그대로다. 방화벽 규칙을 이 식으로 계산해도 된다는 뜻이다(3.9.6).
3.2.12.2 도메인이 바뀌어도 멀티캐스트 그룹은 그대로다
위 표에서 놓치기 쉬운 것 — 주소는 네 도메인 모두 239.255.0.1이고 포트만 바뀐다.
방화벽·스위치 정책에 직접 영향이 있다. "도메인별로 멀티캐스트 그룹을 나눠 격리한다"는 불가능하다 — 그룹이 하나이므로 포트 기반 규칙만이 도메인을 가른다. IGMP 스누핑이나 그룹 단위 ACL로는 도메인을 구분하지 못한다.
반대로 포트로는 명확하게 갈린다. 도메인 $D$ 하나만 허용하려면 $7400 + 250D$ 부근의 좁은 구간만 열면 된다 — 0.4.5가 "도메인 분리는 확실한 격리 수단"이라고 한 근거가 이것이다(다만 보안 수단은 아니다, 13.4).
3.2.12.3 조각 크기는 고정이 아니라 경로에 달렸다
ByteMultiArray 100 KB를 발행하며 UDP 길이 분포를 봤다(Cyclone, 공유 메모리 우회).
| UDP 페이로드 길이 | 관측 수 |
|---|---|
| 1416 B | 73 |
| 13,524 B | 72 |
| 13,536 B | 12 |
| 6,024 B | 12 |
두 무리가 나온다. 1416 B는 이더넷 경로(MTU 1500)의 조각이고 — $1416 + 8_{\text{UDP}} + 20_{\text{IP}} + 14_{\text{Eth}} = 1458 < 1500$ — 13.5 KB 무리는 loopback(MTU 65536) 경로다.
*3.9.13.3이 조각 크기를 1400 B로 가정한 것은 1500 MTU 링크에 한해 맞다. 같은 호스트 안에서는 훨씬 큰 조각이 오가므로, 조각 수로 도달률을 계산할 때는 실제 경로의 MTU를 넣어야 한다.* 무선(1500) 기준이면 그 가정이 유효하고, 점보 프레임이나 loopback이면 다르다.
즉 $P_{\text{도달}} = (1-p)^{\lceil S/M \rceil}$ 의 $M$은 상수가 아니라 경로 파라미터다.
3.2.12.4 확인하지 못한 것
tcpdump가 본 13.5 KB가 실제 와이어 프레임인지는 확정하지 않았다 — 커널의 GSO/GRO 때문에 캡처가 분할 전 크기를 보여 줄 수 있다(확인 필요). 1416 B 무리는 그 영향이 없는 값이다.- 서브메시지 종류별 분해(3.2.4의 HEARTBEAT·ACKNACK·DATA)는 하지 않았다 — 포트와 길이만 봤다.
tcpdump의 RTPS 디코더나 Wireshark가 필요하다(확인 필요). - 도메인 ID 상한(0.4.5가 경고한 임시 포트 충돌)은 시험하지 않았다
(확인 필요).
3.2.10 함정 카탈로그
| # | 함정 | 증상 | 대처 |
|---|---|---|---|
| 1 | 방화벽에서 UDP 7400대만 열고 참가자 다수 | 일부 노드만 연결 | 참가자 수만큼 범위 확보(3.2.6) |
| 2 | 멀티캐스트 주소를 방화벽에서 누락 | 디스커버리 실패 | 239.255.0.1 허용 |
| 3 | 큰 도메인 ID 사용 | 포트 충돌·임시 포트 침범 | 권장 범위·ip_local_port_range 확인 |
| 4 | 대용량 메시지 + 유실 링크 | 거의 전달 안 됨 | 흐름 제어·크기 축소(3.2.7) |
| 5 | 흐름 제어 없이 대용량 전송 | 버퍼 폭주로 오히려 처리량 감소 | 속도 제한 설정 |
| 6 | 무선에서 RELIABLE 대용량 | 꼬리 지연 폭증 | ① 양 감소 → ② BEST_EFFORT — 순서가 중요하다(3.9.13.5) |
| 7 | 캡처 없이 네트워크 문제 추정 | 원인 오판 | tcpdump + Wireshark |
| 8 | 캡처 인터페이스 잘못 지정 | 패킷이 캡처되지 않음 | 멀티캐스트 인터페이스 확인(3.9) |
| 9 | TCP 전송을 성능 개선으로 기대 | 오히려 악화 | 용도를 정확히(3.2.9) |
| 10 | 포트 계산식을 절대적으로 신뢰 | 벤더 설정과 불일치 | ss -ulnp로 확인 |
| 11 | 도메인별로 멀티캐스트 그룹을 나눠 격리 시도 | 그룹은 하나(239.255.0.1) | 포트 기반 규칙만 갈린다(3.2.12.2) |
| 12 | 조각 크기를 1400 B 상수로 가정 | 경로 MTU에 따라 다르다 | 실제 경로로 계산(3.2.12.3) |
3.2.11 체크포인트
- RTPS가 별도로 표준화된 이유와, UDP 위에 신뢰성을 구현한 설계 근거를 말할 수 있는가.
- GUID의 구조와, 그것이 패킷 캡처 분석에서 어떻게 쓰이는지 설명할 수 있는가.
- RTPS 메시지 구조와 주요 서브메시지 여섯 가지의 역할을 말할 수 있는가.
GAP이 없으면 무슨 일이 생기는가. - HEARTBEAT·ACKNACK 순환을 시퀀스로 그릴 수 있는가. 무선에서 이 메커니즘이 왜 악순환을 만드는가.
- 도메인 3의 멀티캐스트 디스커버리 포트와 유니캐스트 사용자 데이터 포트(참가자 2)를 계산할 수 있는가.
- 도메인 ID 상한이 존재하는 이유를 계산으로 설명할 수 있는가. 실무 권장이 이론 상한보다 낮은 이유는?
- 실제 사용 포트를 확인하는 명령은 무엇인가. 왜 계산보다 이것이 정본인가.
- IP 조각화와 RTPS 조각화의 차이는? 유실률 0.1%, 조각 4000개일 때 전달 성공률을 계산할 수 있는가.
- 흐름 제어가 없을 때 오히려 처리량이 떨어지는 이유는?
- 패킷 캡처로만 알 수 있는 두 가지 측정은 무엇이며, 각각 어떤 문제를 가리키는가.
- TCP 전송이 적합한 상황 세 가지와, 그것이 성능 개선책이 아닌 이유를 말할 수 있는가.
- 도메인이 바뀌면 멀티캐스트 주소와 포트 중 무엇이 바뀌는가. 방화벽에 뜻하는 바는(3.2.12.2).
- 조각 크기를 상수로 가정하면 안 되는 이유는(3.2.12.3).
다음 장 3.3은 이 프로토콜 위에서 노드들이 서로를 찾는 과정 — SPDP·SEDP 디스커버리와, 그것이 그래프 규모에 따라 어떻게 급증하는지를 다룬다.