boost asio
전에 boost에 대해서 설명한 바가 있고, 설치하여 사용하는 법까지 알아보았다.
이번에는 네트워크 통신에 자주 사용이 되고 있는 boost asio의
동기식 채팅 예제를 들면서 Winsock와 비교하면서 알아보겠다.
synchronous_server.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #include <boost/asio.hpp> #include <iostream> #pragma warning (disable : 4996); constexpr char SERVER_IP[] = "127.0.0.1"; constexpr unsigned short PORT_NUMBER = 1234; int main() { boost::asio::io_service io_service; boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), PORT_NUMBER); boost::asio::ip::tcp::acceptor acceptor(io_service, endpoint); boost::asio::ip::tcp::socket socket(io_service); acceptor.accept(socket); std::cout << "Client Enter" << std::endl; while(1) { std::array<char, 128> buf; buf.assign(0); boost::system::error_code error; size_t len = socket.read_some(boost::asio::buffer(buf), error); if (error) { if (error == boost::asio::error::eof) { std::cout << "Connect lost client" << std::endl; } else { std::cout << "error No: " << error.value() << "error Message: " << error.message() << std::endl; } break; } std::cout << "Client's message: " << &buf[0] << std::endl; char echoMessage[128] = { 0, }; sprintf_s(echoMessage, 128 - 1, "%s", &buf[0]); int nMsgLen = strnlen_s(echoMessage, 128 - 1); boost::system::error_code ignored_error; socket.write_some(boost::asio::buffer(echoMessage, nMsgLen), ignored_error); std::cout << "Client's Message: " << echoMessage << std::endl; } getchar(); return 0; } | cs |
1 | boost::asio::io_service io_service; | cs |
boost::asio::io_service는 Boost.asio의 핵심 중의 핵심으로.
io_service는 커널에서 발생한 io 이벤트는 디스패치( 다중 작업 중 높은 작업 수행을 위한 자원 할당)
을 해주는 클래스이며, io_service를 통해서 접속 받기, 접속하기, 데이터 받기, 데이터 보내기가 가능해진다.
즉, boost에서 socket을 생성하여 접속 및 데이터 송수신 처리를 위해서는 io_service가 필수인 셈이다.
1 2 | boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), PORT_NUMBER); boost::asio::ip::tcp::acceptor acceptor(io_service, endpoint); | cs |
endpoint는 네트워크 주소를 설정한다.
acceptor 클래스는 클라이언트의 접속을 받아들이는 역할을 한다.
즉 위의 코드의 경우에는 endpoint로 네트워크 주소를 설정해준 이후에
endpoint와 io_service를 연결시켜 클라이언트의 접속을 받는다.
1 2 | boost::asio::ip::tcp::socket socket(io_service); acceptor.accept(socket); | cs |
위의 소스코드는 tcp를 사용하도록 명시하였기 때문에.
클라이언트에 할당될 socket을 만들어야 한다.
그리고 그 소켓을 통해서 클라이언트가 보낸 메시지를 주고 받아야 하기 때문에
io_service에 할당을 해줘야 한다.
1 | size_t len = socket.read_some(boost::asio::buffer(buf), error); | cs |
socket의 멤버함수인 read_some을 사용하여 클라이언트가 보낸 데이터를 받는다.
인자로 데이터를 받을 버퍼와 에러 코드를 받을 error_code를 사용하며 데이터를 받으면
받은 데이터 크기를 반환하게 된다.
1 2 3 4 5 6 7 8 9 10 | if (error) { if (error == boost::asio::error::eof) { std::cout << "Connect lost client" << std::endl; } else { std::cout << "error No: " << error.value() << "error Message: " << error.message() << std::endl; } break; } | cs |
error_code를 조사해서 클라이언트가 받은 데이터의 에러 유무를 조사한다.
클라이언트의 접속이 끊어지는 경우에는 read_some을 통해서 알 수 있다.
이때는 eof 값이 들어가기 때문에, 적절하게 출력 및 종료를 시켜주면 된다.
1 | socket.write_some(boost::asio::buffer(echoMessage, nMsgLen), ignored_error); | cs |
이제 write_some을 통해서 write 작업을 해준다.
이 부분도 read_some처럼 error_code를 함께 인자를 주어 보내지만, 보낼 데이터의 크기를 미리
지정하여 지정한 데이터 크기만큼 보낸다.
※ 본 글은 개인 포트폴리오 혹은 공부용으로 사용하기 때문에, 무단 복사 유포는 금지하지만, 개인 공부 용도로는 얼마든지 사용하셔도 좋습니다
'C_C++ 프로그래밍 > boost' 카테고리의 다른 글
[boost asio] 동기식 echo 채팅 클라이언트 (0) | 2019.07.31 |
---|---|
[boost] 윈도우에 boost를 설치해보자 (0) | 2019.07.11 |
[boost] boost란 무엇인가? (0) | 2019.07.11 |
댓글