Boost ๋น๋๊ธฐ ํต์ ์๋ฒ&ํด๋ผ์ด์ธํธ๋ฅผ ์ ๋ฆฌ์ค...
ํ์ ๊ฐ๋ ์ธ Asio์ ๋ํด์ ๋จผ์ ์ ๋ฆฌํด์ผ๊ฒ ๋ค ์๊ฐ๋ค์ด์
๋ฐ๋ก ๊ฒ์๊ธ๋ก ๋บ๋ค ใ ใฑใด
boost ํํ์ด์ง์ ์ค๋ช ์ด ์ ๋์ด์์ด์, ์๊ฑธ ์ ๋ฆฌํ๋ ค๊ณ ํ๋ค
(์ฒจ๋ถ ๋งํฌ ์ฐธ์กฐ)
1. Boost.Asio ( Asynchronous I/O ) ๊ฐ ๋ญ์ง?
Boost ๊ณต์ํํผ: Boost.Asio is a cross-platform C++ library for network and low-level I/O programming that provides developers with a consistent asynchronous model using a modern C++ approach.
cf) ์ด๋ค ์ด์์ฒด์ ์ฌ๋, ์คํ ๊ฐ๋ฅํ๊ฒ ๋์ํ๊ฒ ํ ์ ์๋ ํ๋ซํผ์ด ํฌ๋ก์ค ํ๋ซํผ
๋จผ์ , Asio์ Async I/O์ ์ค์๋ง์ด๊ณ ๋ป๋๋ก ํด์ํ๋ฉด ๋น๋๊ธฐ I/O์ด๋ค.
์ฐ๋ฆฌ๊ฐ Asio ๋ฐฉ์์ผ๋ก ์์ผ ํต์ ์ ๊ตฌํํ ๋,
๋ฆฌ๋ ์ค์์๋ EPOLL, ์๋์ฐ์์๋ IOCP๋ผ๋ ๊ฒ์ ์ฌ์ฉํ ํ ๋ฐ
์์ผ ํต์ ์ ์ปค๋๊ณผ ์ดํ๋ฆฌ์ผ์ด์ ์ฌ์ด๋ง ๊ณ ๋ คํด๋ ๊ตฌํํ ๊ฒ ์ฐธ ๋ง๋ค
์์ผ ํต์ ๊ด๋ฆฌ๋ ํด์ฃผ๊ณ , ์ด์์ฒด์ ๊ตฌ๋ถ ์์ด ์ฌ์ฉ ๊ฐ๋ฅํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ
boost์์ ๋ง๋ Boost.Asio ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค
2. Sync I/O ๊ณผ Async I/O
Boost์์ Asio๊ฐ ์ด๋ป๊ฒ ๋์ํ๋์ง ์์๋ณด๊ธฐ ์ด์ ์,
I/O ๋ฐฉ์์ ๋ํด์ ๋จผ์ ์ ๋ฆฌํ๋ ค๊ณ ํ๋ค
I/O ๋ฐฉ์์ ๋๊ธฐ์(Sync)๊ณผ ๋น๋๊ธฐ์(Async) ๋ ๊ฐ์ง๊ฐ ์๋ค
Blocking๊ณผ Non-blocking ๋น์ทํ ๊ฐ๋ ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค (๋ฌผ๋ก ๋ค๋ฆ!)
๋๊ธฐ์์ด๋... ๋ธ๋กํน์ด๋... ๋น๋๊ธฐ๋.... ๋ ผ๋ธ๋กํน์ด๋...
์ด๊ฑฐ๋ ์์์ผํ ๊ฒ ๋ง์์, ๊ธ์ ๋ง์ง๋ง์ ์ด์ง ์ ๋ฆฌ๋ง ํด๋๊ฒ ๋ค ↓
์ฐ์ Sync Blocking I/O์ Async Non-Blocking I/O์ ๋ํด์๋ง ๋ค๋ฃจ๊ฒ ๋ค
(1) Sync I/O (Blocking์ผ ๋)
I/O๋ฅผ ํ ๋, ์ดํ์์ Readํ๊ณ Write๋ฅผ ํธ์ถํด์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ด๋ค
Sync I/O๋ ๋จ์ํ ์ดํ์์ Read()๋ฅผ ํธ์ถํ์ฌ I/O ๊ธฐ๋ฅ์ ์ํํ๊ณ ,
์ปค๋์ด ๋ค ์ฝ์ด์ ์ค ๋๊น์ง ๊ธฐ๋ค๋ฆฐ๋ค
์ปค๋์ ๋ค ์ฝ์ผ๋ฉด ์ดํํํ ์ฝ์ Data์ Read() ํจ์์ ๊ฒฐ๊ณผ ๊ฐ์ ์ค๋ค
Sync I/O๋ ์ดํดํ๊ธฐ ์ฝ๊ณ , ๋จ์ํ ์ปค๋์ ์๋ต์ ๊ธฐ๋ค๋ฆฌ๊ธฐ๋ง ํ๋ฉด ๋ผ์,
์ฒ๋ฆฌ ๋ฐฉ๋ฒ๋ ๊ฐ๋จํ๋ค๋ ์ฅ์ ์ด ์๋ค
๊ทธ๋ฌ๋, ๋ค ์ฝ์๋ค๋ ์๋ต์ด ์ค๊ธฐ์ ๊น์ง ์ดํ์ blocking ๋๊ณ ,
๋ค๋ฅธ๊ฑด ํ ์ ์์ผ์ ..
EPOLL์ ์ฌ์ฉํด์, socket FD๋ฅผ ๋ฑ๋กํด์ Non-blocking์ผ๋ก ๊ตฌํํ ์๋ ์์
ํ์ง๋ง boost.Asio๋ก ๊ตฌํํ ๊ฑฐ๋๊น non-blocking์ ์๋ตํ๊ฒ ์
(2) Async I/O (Non-Blocking์ผ ๋)
I/O๋ฅผ ํ ๋, ์ดํ์์ Readํ๊ณ Write๋ฅผ ํธ์ถํด์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ฐ๋๊ฑด
Sync์ผ ๋์ Async์ผ ๋ ๋ชจ๋ ๊ฐ์ ๊ธฐ๋ฅ์ ์ํํ๋ค
Async์ผ ๋ ๋ค๋ฅธ ์ ์ ๊ทธ๋ฌ๋ฉด ๋ฌด์์ด๋..
์ดํ์ Read()๋ฅผ ํธ์ถํด์ ์ปค๋ํํ ์ฝ์ด์ฃผ์ ํ๋ฉด
์ปค๋์ ใ ใ ์ฝ๊ณ ์๋ ค์ฃผ๊ฒ ์ ํ๊ณ ์ฟจํ๊ฒ ์ฝ์ผ๋ฌ ๊ฐ๋ค
Read() ํธ์ถ์ ํ๊ณ , ์ฝ์ ๊ฒฐ๊ณผ์๋ ์๊ด ์์ด ๊ฒฐ๊ณผ๋ฅผ return ๋ฐ๋๋ค
๊ทธ๋ฌ๋ฉด ์ดํ์ ์ปค๋์ด ๋ค ์ฝ์๋ค๋ ๊ฒฐ๊ณผ๋ฅผ ์๋ ค์ฃผ๊ธฐ ์ ๊น์ง
๋ค๋ฅธ ์์ ์ ํ๊ณ ์์ ์ ์๋ค
์ปค๋์ ๋ค ์ฝ์ผ๋ฉด, ์ฝ์ Data๋ ๊ฒฐ๊ณผ ๊ฐ์ ์ดํ์๊ฒ ์๋ ค์ฃผ๋๋ฐ,
์ด ๋๋ ๋ค ์ฝ์๋ค! ๋ผ๋ signal๋ง ์ค ์๋ ์๊ณ , callback ํํ๋ก ์๋ ค์ค ์ ์๋ค
์ดํ์ ์ปค๋์ด ์ฝ์๋ค๊ณ ์๋ ค์ค ๋๊น์ง ๋ค๋ฅธ ์ผ ํ๋ค๊ฐ
์ฝ์๋ค๊ณ ํ๋ฉด, ๋ญ ์ฝ์๋ ๋ณด๋ฉด ๋๋ ๊ฒ์ด๋ค
์์ฃผ ํจ์จ์ ์ด๊ตฐ.
3. Boost.Asio ์ฌ์ฉ ๋ฐฉ๋ฒ
Boost.Asio๋ ์์ผ์ด๋ ๋น์ทํ ์ญํ ์ ํ๋ I/O Object๋ผ๋ ๊ฒ์ผ๋ก
Sync์ Async I/O๋ฅผ ๋๋ค ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค
I/O Object๋ ๋ค์๊ณผ ๊ฐ์ด ๊ฐ์ฒด์ ์ธ์ผ๋ก ์ฌ์ฉํ๋ฉด ๋๋ค
#include <boost/asio.hpp>
boost::asio::io_context io_context;
(io_service ์ฌ์ฉ์ด io_context๋ก ๋ฐ๋์๋ค๊ณ ํ๋ค;;;)
ํ๋ก๊ทธ๋จ์๋ io_context ๊ฐ์ฒด ๊ฐ์ I/O ๊ธฐ๋ฅ์ ์คํํ ์ ์๋ ๋ฌด์ธ๊ฐ๊ฐ ์๊ฒ ๋๋ค
์๊ฑธ ์ด์ฉํด์, socket ํต์ ๋ ํ๊ณ ~ ์๋ฌ ๋ฐ์ํ๋ฉด ์๋ฌ๋ ์ฒ๋ฆฌํ๊ณ ~
Boost Asio๊ฐ ์๋ ์ฐ๋ฆฌ๊ฐ ์ปค๋์ ํตํด I/O ์์ ์ ํ๋๊ฑธ ์ค๊ฐ์์ ๋์ ํด์ฃผ๋๊ฑฐ๋ผ๊ณ
์๊ฐํ๋ฉด ์ดํด๊ฐ ์ฝ๊ฒ ๊ฐ ๊ฒ์ด๋ค
soket FD๋ฅผ ์ฌ์ฉํด์ Read() Write() ํ๋ฏ์ด
io_context๋ฅผ ์ฌ์ฉํด์ Read() Write() ํ๋๊ฑฐ๋ค
๊ทธ๋ฌ๋ฉด boost์์ io_context๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํด์ผํ๋์ง
Sync์ Async ๊ตฌํ์ ๋๋ ์ ๋ณด๋๋ก ํ๊ฒ ๋ค
(io_service๋ io_context๊ฐ ๊ฐ์๊ฑฐ์)
(1) Boost.Asio - Sync
TCP ํด๋ผ์ด์ธํธ์ผ ๋๋ฅผ ์๋ก ๋ค์ด๋ณด์
์์ ๊ทธ๋ฆผ์ Boost ํํ์ด์ง์ ์๋๊ฑด๋ฐ, ์๋ ์ค๋ช ์ ์กฐ๊ธ ๋ง๋ถ์ฌ์ ์ ๋ฆฌํ๊ฒ ๋ค
์ฐ๋ฆฌ ํ๋ก๊ทธ๋จ์์ io_context ๊ฐ์ฒด๋ฅผ ์ต์ ํ๊ฐ๋ ๊ฐ๊ณ ์์ง ์์๊ฐ?
๊ทธ๋ฌ๋ฉด ์ io_context๋ฅผ ํตํด TCP socket์ ๋ฑ๋กํ ์ ์๋ค
boost::asio::io_context io_context;
boost::asio::ip::tcp::socket socket(io_context);
๋ฐ๋ก ์๋ ๊ฒ. ๊ทธ๋ฌ๋ฉด socket๊ณผ io_context๊ฐ ๋ฑ๋ก(?) ๋๋ค๊ณ ํ ์ ์๊ฒ ๋ค
์ด๋ ๊ฒ ์ฐ๊ฒฐ๋ ์์ผ์ผ๋ก I/O operation์ ์ํํ ์ ์์ผ์๊ฒ ๋ค.
์ดํ ๋์์ ๊ทธ๋ฆผ์ ์๋ ๋ฒํธ์ ํจ๊ป ์ ๋ฆฌํ๊ฒ ๋ค
1. ํด๋ผ์ด์ธํธ๋ผ๋ฉด ์๋ฒ์ ์ฐ๊ฒฐ์ ํด์ผํ์ง ์๋๊ฐใ ใ
tcp::socket socket(io_context);
boost::asio::connect(socket, endpoint);
endpoint๋ ๋ญ์ง? ๋ผ๊ณ ์๊ฐ์ด ๋คํ ๋ฐ,
๋น์ฐํ connect๋ฅผ ํ๋ ค๋ฉด, ์ฐ๊ฒฐํ ์๋ฒ์ IP ์ฃผ์์ Port ๋ฒํธ๋ฅผ ์์์ผํ๋ค
tcp::resolver resolver(io_context);
tcp::resolver::query query("localhost", "7777");
tcp::resolver::iterator endpoint = resolver.resolve(query);
endpoint๋ resolver๋ผ๋ ๊ฒ์ ํตํด์ ํ ์ ์๋ค
resolver๋ ์ฐ๊ฒฐํ๊ณ ์ ํ๋ ์๋ฒ์ ์ฃผ์์ ๋ํด DNS query๋ฅผ ํด์ค๋ค
์ฆ, ์ดํ์์ DNS ์ด๋ฆ์ ํ์ธํด์ฃผ๋ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํด์ค๋ค ใ
(์ค์ ์ฐ๊ฒฐํด์ค ์ ์๋ ์ฃผ์์ธ์ง ์๋์ง)
2. io_context๋ I/O Execution context์ ์ ๋ฌํ๋ ์ญํ
์ดํ๊ณผ ์ปค๋ ์ฌ์ด์ ์ค๊ฐ ๋ค๋ฆฌ ์ญํ ์ ํด์ฃผ๋ ๊ฒ์
3. io_context๋ ์ํํ๊ณ ์ํ๋ I/O ์์ ์ ์ด์์ฒด์ ํํ ์๋ ค์ค
4. ์ด์์ฒด์ ๋ I/O ์์ ์ ์คํํ ๊ฒฐ๊ณผ๋ฅผ io_context์๊ฒ return ํด์ค
5. return ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ io_context๋ ์ดํํํ ๊ฒฐ๊ณผ๋ฅผ ์๋ ค์ค์ผ ํจ
์ด๋ป๊ฒ? boost::system::error_code๋ฅผ ํตํด์
6. ๊ฒฐ๊ณผ๋ ๋ฐ๋๊ฑด ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ๋ฐ์
1) error_code๋ฅผ ํตํด์ ๋ฐ๊ธฐ
boost::system::error_code ec;
socket.connect(server_endpoint, ec);
ํ๋ผ๋ฏธํฐ๋ก ๋ฃ์ด์ ๋ฐ์์ค๋ฉด ๋จ ใ
2) I/O object๊ฐ throws ํด์ฃผ๋ exception์ผ๋ก ๋ฐ์์๋ ๋จใ
(2) Boost.Asio - Async
๊ทธ๋ฌ๋ฉด ๋น๋๊ธฐ์ผ ๋๋ ์ด๋ป๊ฒ ๋ฌ๋ผ์ง๊น๋ฅผ ๋ณด๊ฒ ๋ค
1. connect๋ฅผ ํ๋๊ฑด ๋๊ฐ์๋ฐ, ํจ์์ ์ด๋ฆ๋ง ๋ฌ๋ผ์ง๋ค
socket.async_connect(server_endpoint, your_completion_handler);
connect() ๋์ async_connect() ํจ์๋ฅผ ์ฌ์ฉํ๊ณ ,
๋น๋๊ธฐ ํต์ ์ด๊ธฐ ๋๋ฌธ์, ๋๋ฒ์งธ ํ๋ผ๋ฏธํฐ์ callback ํจ์๋ง ๋ฑ๋กํด์ฃผ๋ฉด
์คํ๊ฒฐ๊ณผ์ ๋ํด callback์ ํตํด ๋ฐ์ ์ ์๋ค
2. I/O ๊ฐ์ฒด๋ฅผ ํตํด I/O ์คํ context์๊ฒ ์์ฒญ์ ์ ๋ฌํ๋ค ~_~
3. I/O ์คํ context๋ ์ดํ์ด ์์ฒญํ Asynchronous connect์ ๋ํด
์ด์์ฒด์ ์๊ฒ signal์ ๋ณด๋ธ๋ค
↑ ์ฌ๊ธฐ๊น์ง์ ๊ณผ์ ์ ์ฌ์ค ๋๊ธฐ์ ๋ฐฉ์๊ณผ ๋น์ทํ๋ฐ,
๋ค๋ฅธ๊ฑด ์๊ฐ์ด๋ค.
์ด์์ฒด์ ์ I/O ์์ ์ด ์ ๋ฌ๋๋ ๋์์ ์๊ฐ์ ๋น๋๊ธฐ์์์๋ ํฌํจ๋์ง ์๋๋ค
4. OS๋ I/O ์์ ์ ๋ํด ์๋ฃ๊ฐ ๋๋ฉด, io_context์๊ฒ ์๋ ค์ค
5. ์ดํ์์๋ ๋น๋๊ธฐ ์์ ์ ๋ํด ์์ํ๋ค๋ ์๋ฏธ๋ก io_context::run()๋ฅผ ํธ์ถํด์ผ ํจ
6. io_context๋ ์คํ ๊ฒฐ๊ณผ์ ๋ํด callback ํจ์์ ์ ๋ฌํ๋ค
↑ ์์ ๊ทธ๋ฆผ์์ ํ์ดํ์ ๊ทธ๋ฅ ์ ์ ์ด ์๋๋ฐ
๋น๋๊ธฐ์์ด๋๊น ๊ตณ์ด ์์๊ฐ ์๋ ๋จ๊ณ(?)๋ก๋ง ์๊ฐํ์
์ค์ง์ ์ธ ์ฝ๋๋ ๋ค์ ๊ธ์์.....
cf) Sync & Async & Blocking & Non-Blocking ์ฐจ์ด์
์๊ฑด ์ค๋ ์ฃผ์ ๋ฅผ ์ ๋ฆฌํ๋ฉด์ ์๊ฒ๋๊ฑด๋ฐ, ์ฒจ๋ถ๋งํฌ์ ์๋ ์๋ฐ์ง๊ธฐ ๋์ ๊ธ์ ์ฐธ๊ณ ํด์ ์ ๋ฆฌํ๋ฐ
system call์ ์ดํดํ๊ธฐ ์ฝ๊ฒ ํจ์ ํธ์ถ์ด๋ผ ์นญํ๊ฒ ๋ค
1. Sync & Async ์ฐจ์ด๋? → ๋๊ฐ ํจ์ ์๋ฃ ์ํค๋์ง๊ฐ ์ค์
- Sync: ์ดํ์์ ํธ์ถํ ํจ์์ ์๋ฃ๋ฅผ ๊ธฐ๋ค๋ฆผ (ex. return ๊ฒฐ๊ณผ)
- Async: ์ปค๋์์ ์ดํ์ด ํธ์ถํ ํจ์๋ฅผ ์๋ฃ์ํค๊ณ , ์ดํ์ ์ ๊ธฐ๋ค๋ฆฌ๊ณ ๋ค๋ฅธ๊ฑฐ ํจ
- (ex. callback ๋ฑ๋ก ํ ๋ค๋ฅธ๊ฑฐ ํจ)
2. Blocking & Non-Blocking ์ฐจ์ด๋? → ์ธ์ returnํ๋์ง๊ฐ ์ค์
- Blocking: ์ดํ์ด ํจ์๋ฅผ ํธ์ถ → ์ด์์ฒด์ ๋๊ธฐ ํ์ ๋ฑ๋ก → ํจ์ ์คํ ์๋ฃ ํ ๊ฒฐ๊ณผ๋ฅผ return ๋ฐ์
- Non-Blocking: ์ดํ์ด ํจ์๋ฅผ ํธ์ถ → ์คํ์๋ฃ ๋๋ ์๋๋ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ก return ๋ฐ์
3. Sync & Blocking ์ฐจ์ด๋?
- Sync: ์ดํ์์ ํจ์ return ์๋ฃ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋์ ๋๊ธฐ ํ์ ๋จธ๋ฌผ์ง ์์๋ ๋จ (ํ์X)
- O_NONBLOCK ์ต์ ๋ฑ์ ์ฌ์ฉํด์ Non-blocking์ผ๋ก ๋ฐ๋ก return ๋ฐ์ ์ ์์
- Blocking: ์ดํ์์ ํจ์ return ์๋ฃ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋์ ๋๊ธฐ ํ์ ๋จธ๋ฌผ๋ฌ์ผ ํจ (ํ์ O)
- ์๋ฃ๋์ด์ return ๋ฐ์ ๋๊น์ง ํต๊ณ ์~
4. Async & Non-Blocking ์ฐจ์ด๋?
- Async: ํจ์ ์คํ์ด ์ ๋๋ค!์ ๋ํ ๊ฒฐ๊ณผ๊ฐ ์๋๋ผ ํจ์ ์คํ ํ๋ค!์ ๋ํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ก return
- Non-Blocking: ํจ์ ์คํ์ด ์ ๋๋ค! ๋ฐ์ดํฐ๊ฐ ์์ด์ ์ฝ์ ์๋ ์๋ค!์ ๋ํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ก return
* Boost Asio ์ค๋ช
www.boost.org/doc/libs/1_76_0/doc/html/boost_asio/overview/core/basics.html
* Sync&Async I/O ์ค๋ช
developer.ibm.com/technologies/linux/articles/l-async/
์ฝ๋๋ก๋ง ๊ฐ๋ฐํ๋๊ฑฐ์ ๋ํด
๊ฐ๋ ์ ์ดํดํ๋ ค๋๊น ๋์น ๋ถ๋ถ์ด ๋ง์๋ค
์ด์ ๋ผ๋ ์๋ฉด ๋ผ
'๐ C๋ C++' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Boost-echo tcp client & server๋ฅผ ์ดํด๋ณด์ (1) (2) | 2021.06.11 |
---|---|
C++ ์ค๋งํธ ํฌ์ธํฐ๋ฅผ ์์๋ณด์ - (1) unique_ptr (0) | 2021.05.25 |
C++ ํด๋์ค ๋ฉค๋ฒ๋ณ์ ์ด๊ธฐํ๋ฅผ ์์๋ณด์ (4) | 2021.03.25 |
C++ ๋๋ฌธ์/์๋ฌธ์ ๋ณํ (4) | 2021.02.26 |
C++ Function Object (ํจ์ ๊ฐ์ฒด)๋ฅผ ์์๋ณด์ (4) | 2021.01.22 |