C++ 통신 공부를 위해 Boost::Asio를 사용해 봤다. 아무 생각 없이 예제 보며 따라만들다가 클래스화해볼까 하고 멋대로 아무 설계도 없이 클래스화하고 했더니 난리가 났다 (._.
다음부터 짤땐 제대로 설계하고 만들어야겠다 ㅠㅠ
1. EchoClient
1-1. EchoClient.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <iostream> #include <boost/asio.hpp> class EchoClient { private: boost::system::error_code m_error; boost::asio::io_service m_io_service; boost::asio::ip::tcp::socket m_socket; boost::asio::ip::address m_server_ip; int m_server_port; public: EchoClient(char *server_ip, int port); ~EchoClient(); bool connect_server(); bool send_message(const char *); bool recv_message(char* recv_buffer, int size); void print_error(const char *prev_message); }; | cs |
일단은 EchoClient의 헤더 파일입니다.
대충대충 넘겨서 짰더니 박살이 났습니다 ㅠㅠ
1-2. EchoClient.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 | #include "EchoClient.h" EchoClient::EchoClient(char *server_ip, int port) : m_socket(m_io_service) { m_server_ip = boost::asio::ip::address::from_string(server_ip); m_server_port = port; } EchoClient::~EchoClient() { } bool EchoClient::connect_server() { auto endpoint = boost::asio::ip::tcp::endpoint(m_server_ip, m_server_port); m_socket.connect(endpoint, m_error); if (m_error) return false; return true; } bool EchoClient::send_message(const char *message) { m_socket.send(boost::asio::buffer(message, strlen(message) + 1), boost::asio::socket_base::message_out_of_band, m_error); if (m_error) return false; return true; } bool EchoClient::recv_message(char *recv_buffer, int size) { memset(recv_buffer, 0, size); m_socket.read_some(boost::asio::buffer(recv_buffer, size), m_error); if (m_error) return false; return true; } void EchoClient::print_error(const char *prev_message) { if(m_error) std::cout << prev_message << " : " << m_error.message() << " (" << m_error.value() << ")" << std::endl; } |
EchoClient.h 내의 멤버함수를 구현해둔 EchoClient.cpp 입니다.
소멸자는 딱히 만들필요 없었지만 처음 만들때 멤버변수로 힙에 할당하는게 있어서 해제할려고 만들었다가 삭제해버렸습니다.
1-3. Main.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 | #include <iostream> #include <string> #include "EchoClient.h" #define BUF_SIZE 1024 using namespace boost; int main() { EchoClient client("127.0.0.1", 25252); if (!client.connect_server()) { client.print_error("Connect Error"); return -1; } std::string message; char *recv_buffer = new char[BUF_SIZE]; while (true) { std::cout << "Input : "; std::getline(std::cin, message); if (message == "exit") break; if (!client.send_message(message.c_str())) { client.print_error("Send Message Error"); break; }; if (!client.recv_message(recv_buffer, BUF_SIZE)) { client.print_error("Recv Message Error"); break; }; std::cout << "Output : " << recv_buffer << std::endl; std::cout << "====================================" << std::endl; } delete[] recv_buffer; return 0; } | cs |
127.0.0.1의 25252 포트에 연결하여 입력받은 문자열을 반복하여 보내고, 받아서 출력합니다.
2. EchoServer
2-1. EchoServer.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <boost/asio.hpp> #include <boost/bind.hpp> #include <boost/thread.hpp> #include <memory> #include <iostream> typedef std::shared_ptr<boost::asio::ip::tcp::socket> sock_ptr; class EchoServer { private: boost::system::error_code m_error; boost::asio::io_service m_io_service; int m_port; public: EchoServer(int port); void start(); }; | cs |
서버인데 클라이언트보다 짧은 것은 기분탓은 아닐겁니다 ㅠ
2-2. EchoServer.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 | #include "EchoServer.h" #define BUF_SIZE 1024 void echo(sock_ptr sock); EchoServer::EchoServer(int port) { m_port = port; } void EchoServer::start() { sock_ptr sock(new boost::asio::ip::tcp::socket(m_io_service)); boost::asio::ip::tcp::acceptor acc(m_io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), m_port)); acc.accept(*sock); boost::thread th(boost::bind(echo, sock)); th.join(); } void echo(sock_ptr sock) { size_t length; char data[BUF_SIZE]; boost::system::error_code error; try { while (true) { memset(data, 0, BUF_SIZE); length = sock->read_some(boost::asio::buffer(data, BUF_SIZE), error); if (error == boost::asio::error::eof) break; else if (error) { throw boost::system::system_error(error); } std::cout << data << std::endl; boost::asio::write(*sock, boost::asio::buffer(data, length)); } } catch (std::exception& e) { std::cerr << "Error in echo : " << e.what() << std::endl; } } | cs |
솔직히 말하면 짜기 힘들었습니다.
처음이기도 하고 상당히 난해한게 많아서 ㅠㅠ
2-3. Main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include "EchoServer.h" #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0500 // 윈도우 2000 이상 지원 #endif int main() { try{ EchoServer server(25252); server.start(); } catch (std::exception& e) { std::cout << "Exception in Main : " << e.what() << std::endl; } return 0; } | cs |
'Programming' 카테고리의 다른 글
현재 사용중인 Python 라이브러리 (0) | 2017.06.15 |
---|---|
[Python] logging 모듈 중복 로깅 문제 해결법 (4) | 2017.05.08 |
[C++] Boost 설치 & 빌드 환경 구축 (0) | 2016.12.20 |
[C++] unique_ptr, weak_ptr (0) | 2016.12.15 |
[C++] auto_ptr, shared_ptr (0) | 2016.12.14 |
__미니__
E-mail : skyclad0x7b7@gmail.com 나와 계약해서 슈퍼 하-카가 되어 주지 않을래?