클라이언트 프로그램
📌 개요
- 클라이언트(Client) = 서버에 접속해 서비스를 요청하는 쪽
- 로봇 운영의 두 종류 클라이언트: 로봇 위에서 돌며 상태를 보고하는 로봇 측 에이전트, 운영자가 쓰는 사용자 UI 클라이언트(웹·모바일 앱)
- 출제 포인트: 클라이언트 소켓 흐름(socket→connect), 동기/비동기 호출, 하트비트·재연결 같은 연결 관리 기법, JSON·XML·Protocol Buffers 등 데이터 직렬화 형식의 비교
📖 핵심 개념
로봇 운영에서 클라이언트의 두 얼굴
- 로봇 측 에이전트(Agent): 로봇 제어기(또는 탑재 PC)에서 실행되며 서버로 먼저 접속해 나가는 프로그램. 상태·센서 데이터 업로드, 작업 지시 수신, OTA 업데이트 수신을 담당한다. 방화벽 내부에서 바깥으로 나가는 연결은 허용되기 쉬우므로 로봇이 클라이언트가 되는 구조가 일반적이다
- 사용자 UI 클라이언트: 운영자·사용자가 로봇을 조회·조작하는 화면. 웹 브라우저 기반, 모바일 앱, PC 전용 프로그램 형태가 있다
클라이언트 소켓 프로그래밍 흐름
TCP 클라이언트의 함수 호출 순서는 서버보다 단순하다.
socket()— 소켓 생성connect()— 서버의 IP·포트로 접속 요청send()/recv()— 데이터 송수신close()— 연결 종료
- 서버와 달리
bind()·listen()·accept()가 없음 - 이유: 클라이언트는 기다리는 쪽이 아니라 찾아가는 쪽이기 때문 (서버 흐름은 서버 프로그램 참조)
통신 패턴 — 요청-응답 vs 발행-구독
- 요청-응답(Request-Response): 클라이언트가 물으면 서버가 답한다. HTTP/REST가 대표적. 명확하고 단순하지만, 서버 쪽 변화를 알려면 클라이언트가 반복해서 물어야 한다(폴링)
- 발행-구독(Publish-Subscribe): 클라이언트가 토픽을 구독해 두면 새 데이터가 발행될 때마다 받는다. MQTT·DDS·ROS 토픽이 이 방식. 실시간 상태 갱신에 유리하다 (→ 로봇 미들웨어 구조 설계)
동기 호출 vs 비동기 호출
- 동기(Synchronous) 호출: 요청을 보내고 응답이 올 때까지 멈춰서 기다린다. 코드가 단순하지만, 기다리는 동안 다른 일을 못 한다. UI 클라이언트가 동기 호출로 서버를 기다리면 화면이 멈춘(freeze) 것처럼 보인다
- 비동기(Asynchronous) 호출: 요청만 걸어 두고 즉시 다음 일을 진행, 응답이 도착하면 콜백(Callback)·이벤트로 처리한다. UI 반응성이 유지되고 여러 요청을 병행할 수 있지만 코드 흐름이 복잡해진다
로봇 측 에이전트에서 서버 통신이 로봇의 제어 동작을 막아서는 안 된다. 통신은 별도 스레드나 비동기로 처리하고, 제어 루프와는 큐(Queue)로 분리하는 것이 정석이다 (→ 미들웨어 프로세스 관리).
연결 관리 — 끊김을 전제로 설계한다
무선 네트워크 위의 이동로봇은 연결이 언제든 끊길 수 있다는 전제로 클라이언트를 설계해야 한다.
- 하트비트(Heartbeat): 주기적으로 "살아 있음" 신호를 주고받아 상대 생존과 연결 상태를 확인. 일정 시간 하트비트가 없으면 연결 끊김으로 판정
- 타임아웃(Timeout): 응답을 무한정 기다리지 않고 제한 시간을 두어 실패로 처리
- 재연결(Reconnection): 끊기면 자동으로 다시 접속 시도. 즉시 무한 재시도하면 서버·네트워크에 부담을 주므로 지수 백오프(Exponential Backoff, 재시도 간격을 1초→2초→4초처럼 점점 늘림) 를 적용
- 로컬 버퍼링(Local Buffering): 끊긴 동안의 데이터를 로봇에 임시 저장했다가 재접속 후 전송 — 데이터 유실 방지 (→ 오프라인 동기화)
데이터 직렬화 — 보낼 데이터를 어떻게 포장하나
- 직렬화(Serialization) = 프로그램 내부의 데이터 구조(객체)를 전송·저장 가능한 바이트 열로 변환하는 것
- 받은 쪽은 역직렬화(Deserialization)로 복원
| 형식 | 종류 | 특징 |
|---|---|---|
| XML | 텍스트 | 태그 기반, 스키마 검증 강력. 장황해서 용량 큼 |
| JSON | 텍스트 | 키-값 구조, 사람이 읽기 쉽고 웹 표준. XML보다 간결 |
| Protocol Buffers(protobuf) | 이진(Binary) | 스키마(.proto) 정의 후 코드 생성. 작고 빠름, 사람이 직접 읽을 수 없음 |
- 텍스트 형식(JSON·XML)은 디버깅·호환에 유리하고, 이진 형식(protobuf 등)은 대역폭·성능에 유리하다
- 센서 데이터처럼 양이 많고 주기가 빠른 데이터는 이진 직렬화, 설정·API처럼 사람이 다루는 데이터는 JSON이 일반적
UI 클라이언트 설계 포인트
- 웹 기반: 설치 불필요, 어디서나 접속 — 실시간성엔 WebSocket 병용
- 모바일 앱: 현장 이동 중 조회·알림 수신에 유리 (푸시 알림)
- 사용자 특성에 맞춘 화면 설계는 사용자 특성의 분석, 조작 인터페이스 관점은 HRI 인터페이스 참조
📊 다이어그램 · 수식
로봇 측 에이전트의 구조 — 제어와 통신의 분리
graph LR
subgraph 로봇
CTRL["제어 루프
(실시간)"] -- "상태 데이터" --> Q1["송신 큐"]
Q2["수신 큐"] -- "작업 지시" --> CTRL
Q1 --> AG["통신 에이전트
(비동기·별도 스레드)"]
AG --> Q2
AG --- BUF[("로컬 버퍼
끊김 대비 저장")]
end
AG -- "하트비트 · 상태 보고
(끊기면 지수 백오프 재연결)" --> SRV["운영 서버"]
SRV -- "작업 지시 · OTA" --> AG동기 vs 비동기 호출
sequenceDiagram
participant UI as 동기 클라이언트
participant S1 as 서버
UI->>S1: 요청
Note over UI: 응답까지 대기 (화면 멈춤)
S1-->>UI: 응답
participant AC as 비동기 클라이언트
participant S2 as 서버
AC->>S2: 요청 (걸어두기만)
Note over AC: 즉시 다른 작업 계속
S2-->>AC: 응답 도착 → 콜백 처리🎯 핵심 요약 · 암기 포인트
✏️ 예상문제
1. TCP 클라이언트 프로그램의 소켓 함수 호출 순서로 옳은 것은?
① socket → bind → listen → accept ② socket → accept → send/recv → close ③ socket → connect → send/recv → close ④ connect → socket → send/recv → close
정답 및 해설
정답: ③ 클라이언트는 소켓을 만들고(connect 전에 socket이 먼저다) 서버로 접속한 뒤 송수신한다. bind·listen·accept는 서버 쪽 함수다.
2. 무선 네트워크 위의 이동로봇 클라이언트 설계로 적절하지 않은 것은?
① 주기적 하트비트로 연결 상태를 확인한다 ② 연결이 끊기면 즉시, 무한정, 최대한 빠른 주기로 재접속을 반복한다 ③ 응답 대기에 타임아웃을 설정한다 ④ 끊긴 동안의 데이터를 로컬에 버퍼링했다가 재접속 후 전송한다
정답 및 해설
정답: ② 무한 고속 재시도는 서버와 네트워크에 부하 폭주를 일으킨다. 지수 백오프로 재시도 간격을 점점 늘리는 것이 올바른 설계다. ①③④는 끊김을 전제로 한 표준 기법이다.
3. 데이터 직렬화 형식에 대한 설명으로 옳은 것은?
① Protocol Buffers는 텍스트 기반이라 사람이 읽기 쉽다 ② JSON은 XML보다 일반적으로 더 장황하고 용량이 크다 ③ 대량·고주기 센서 데이터에는 이진 직렬화가 대역폭·성능 면에서 유리하다 ④ 역직렬화는 바이트 열을 저장 매체에 기록하는 과정이다
정답 및 해설
정답: ③ 이진 형식은 같은 데이터를 훨씬 작고 빠르게 다룬다. ① protobuf는 이진 형식이고, ② 장황한 쪽은 태그를 반복하는 XML이며, ④ 역직렬화는 바이트 열을 다시 데이터 구조로 복원하는 과정이다.
4. 로봇 측 에이전트에서 서버 통신을 제어 루프와 분리하고 큐로 연결하는 주된 이유는?
① 통신 지연·끊김이 로봇의 실시간 제어 동작을 막지 않도록 하기 위해 ② 직렬화 용량을 줄이기 위해 ③ 서버의 동시 접속 수를 늘리기 위해 ④ 하트비트 주기를 길게 하기 위해
정답 및 해설
정답: ① 통신은 지연·블로킹이 언제든 생길 수 있다. 동기적으로 제어 루프 안에서 통신하면 네트워크가 느려질 때 제어까지 멈춘다. 별도 스레드·비동기 + 큐 분리가 정석이다.
🔗 관련 노트
- 서버 프로그램 — 접속 대상인 서버의 구조
- 로봇 보안 — 클라이언트 인증과 통신 암호화
- 동기화 프로그램 — 오프라인 데이터 동기화
- 미들웨어 프로세스 관리 — 스레드 분리와 큐·동기화
- HRI 인터페이스 — 사용자 클라이언트의 인터페이스 설계
- _MOC 로봇운영소프트웨어