개요
클라이언트는 서버와 통신하는 어플리케이션이며, 서버가 제공하는 서비스를 사용한다.
서버가 제공하는 서비스가 필요하다는 점과 그 서비스를 받기 위해 서버와의 통신을 시작하는 것이 특징이다.
클라이언트 어플리케이션은 서버와 통신할 때 사용하는 전송 계층 프로토콜로 나눌 수 있다.
UDP 프로토콜을 쓴다면 UDP 클라이언트다.
TCP 프로토콜을 쓴다면 TCP 클라이언트다.
물론 클라이언트가 쓸 수 있는 전송 계층 프로토콜은 다른 것도 많다.
게다가 여러 가지 프로토콜을 사용해 통신할 수 있는 다중 프로토콜 클라이언트도 있다.
하지만 일반적으로 소프트웨어에서 가장 널리 쓰이는 프로토콜은 UDP와 TCP이다.
프로그램을 명세에 따라 설계하는 초기 단계에서 통신 시 사용할 전송 계층 프로토콜을 결정해야 한다.
TCP와 UDP 프로토콜은 개념적으로 다르기 때문에 한창 프로그램을 개발하고 난 후에 바꾸는 것은 꽤 어렵다.
클라이언트는 동기냐, 비동기이냐에 따라서도 분류할 수 있다.
동기 클라이언트와 비동기 클라이언트의 구조는 매우 다르기 때문에 둘 중 어떤 방법을 선택할지 프로그램의 요구사항을 세밀히 분석하여 프로그램이 앞으로 어떻게 발전할 것인지, 어떤 새로운 요구사항이 들어올 수 있는지를 잘 확인하여 프로그램의 초기 설계 단계에 결정해야 한다.
Boost.asio에서의 클라이언트는 서버와 네트워크 연결을 통해 데이터를 송수신하는 역할을 한다.
클라이언트는 특정 IP 주소와 포트 번호를 사용해 서버에 연결을 시도한다.
연결이 성공하면 데이터를 전송하거나 받을 수 있다.
동기 클라이언트
동기 클라이언트 어플리케이션은 요청한 연산이 끝나거나 오류가 발생할 때까지 실행 중이던 스레드를 멈춘다.
Boost.asio에서는 관련 API가 모두 존재하며 동기 클라이언트에서는 동기 소켓 API를 사용한다.
I/O파트에서 설명했던 write_some, write, read_some, read가 이에 해당한다.
이 메서드와 함수들은 스레드를 기다리게 하는 방식으로 클라이언트를 동기화시킬 수 있다.
동기 클라이언트의 장점으로 간단하게 구현할 수 있다는 점을 뽑을 수 있다.
개발하기도, 디버깅하기도 쉽고, 비동기 방식에 비해 기능적으로 동일한 것을 지원하는 것도 쉽다.
하지만 동기 방식은 기능상으로 한계가 있다, 이 점 때문에 동기 방식을 선택할 수 없기도 하다.
일단 동기 연산은 시작하면 취소할 수 없거나 원하는 시간보다 오래 실행 중이면 중단하도록 타이머를 설정할 수 없다.
서버에 요청을 보낸 순간부터 서버로 부터 응답을 받기 까지 동기 클라이언트는 작업을 진행할 수 없다.
비동기 클라이언트
동기 방식과 달리 비동기 소켓 API를 사용한다.
async_write_some, async_write, async_read_some, async_read와 같이 API에 async가 붙는 것이 특징이다.
사용중인 스레드가 한 가지 작업에 머물러 있는 것이 아닌 특정 작업을 요청한 후에 다른 작업을 하러 갈 수 있다.
예를 들어 특정 요청 서버에 전달하고 서버로 부터 응답을 받기 까지 기다리지 않는다.
해당 시간에 다른 작업 요청을 위해 스레드는 계속 일을 할 수 있다.
비동기 연산은 연산이 처음에 시작된 곳과는 완전히 다른 부분(콜백)에서 완료된다는 점 때문에 동기보다 복잡하다.
요청과 콜백 함수의 문맥을 유지하기 위해 자유 메모리상에 데이터 구조체를 유조해야한다.
스레드 또한 동기화 해야 하며 프로그램 구조를 복잡하게 만들고 오류가 나기 쉽다.
이 밖에도 비동기 방식은 계산상, 메모리상으로 부하가 좀 더 있어 어떤 상황에선 동기 방식보다 덜 효율적이다.
주요 메서드
- io_context : 비동기 작업을 관리하는 핵심 객체, 클라이언트 프로그램은 io_context 객체를 생성하고, 이를 통해 네트워크 작업을 실행하고 관리한다, 비동기 작업을 수행할 때 run()을 호출해 작업이 완료되도록 유지할 수 있다.
- endpoint : 서버의 IP 주소와 포트를 정의한 객체, 서버에 접속할 때 이정보를 사용한다.
- socket : 실제 네트워크 통신을 수행하는 객체, connect(), async_connect()를 통해 서버와 연결을 시도한다.
- connect : 위에서 언급 했듯이 서버에 연결을 요청할 때 사용하는 메서드이다.
- write : 동기 방식으로 데이터를 출력하는 메서드
- async_wrtie : 비동기 방식으로 데이터를 출력하는 메서드
- read : 동기 방식으로 데이터를 입력하는 메서드
- async_read : 비동기 방식으로 데이터를 입력하는 메서드
- streambuf : 크기를 가변적으로 관리하는 버퍼
- error_code : 송수신 중 발생한 오류나 네트워크 연결 오류 등 에러를 관리하는 클래스
- shutdown : 소켓을 종료하는 메서드
- close : 소켓을 닫는 메서드
'소켓 통신 > Boost' 카테고리의 다른 글
Boost.asio 동기 UDP 클라이언트 (0) | 2024.11.18 |
---|---|
Boost.asio 동기 TCP 클라이언트 (0) | 2024.11.18 |
Boost.asio I/O 소켓 종료하기와 닫기 (1) | 2024.11.14 |
Boost.asio I/O 비동기 연산 취소하기 (0) | 2024.11.14 |
Boost.asio I/O TCP 소켓 비동기적 읽기 (1) | 2024.11.14 |