Boost C++ Libraries/Boost.Asio

Boost.Asio 튜토리얼 - Daytime.6 - 비동기 UDP daytime 서버

까마귀75 2020. 12. 17. 12:11
728x90
반응형

Daytime.6 - 비동기 UDP daytime 서버 (An asynchronous UDP daytime server)

main() 함수

int main()
{
  try
  {


들어오는 클라이언트 요청을 승인하려면 서버 개체를 생성하고 io_context 개체를 실행한다.

    boost::asio::io_context io_context;
    udp_server server(io_context);
    io_context.run();
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}

udp_server 클래스

class udp_server
{
public:


생성자에서 UDP 포트 13번을 수신하도록 소켓을 초기화한다.

  udp_server(boost::asio::io_context& io_context)
    : socket_(io_context, udp::endpoint(udp::v4(), 13))
  {
    start_receive();
  }

private:
  void start_receive()
  {


ip::udp::socket::async_receive_from() 함수는 응용프로그램이 백그라운드에서 새로운 요청을 수신하도록 한다. 새로운 요청이 수신되면, io_context 개체는 두 개의 인수(작업의 성공 유무를 나타내는 boost::system::error_code 유형의 값과 수신된 바이트 수를 지정하는 size_t 유형의 값 bytes_transferred)로 handle_receive() 함수를 호출할 수 있다.

    socket_.async_receive_from(
        boost::asio::buffer(recv_buffer_), remote_endpoint_,
        boost::bind(&udp_server::handle_receive, this,
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
  }


handle_receive() 함수는 클라이언트 요청을 처리한다.

  void handle_receive(const boost::system::error_code& error,
      std::size_t /*bytes_transferred*/)
  {


error 파라미터는 비동기 작업의 결과가 포함되어 있다. 클라이언트의 요청을 포함하는 1 바이트 recv_buffer_만 제공하므로, 클라이언트가 더 큰 크기를 보내면 io_context는 오류를 반환할 것이다. 그런 오류가 발생하면 우리는 무시할 수 있다.

    if (!error)
    {


클라이언트에 응답할 데이터를 설정한다.

      boost::shared_ptr<std::string> message(
          new std::string(make_daytime_string()));


이제 ip::udp::socket::async_send_to()를 호출하여 데이터를 클라이언트에 제공한다. (클라이언트로 데이터를 바로 보내는 것이 아니라, 데이터 전송 서비스에 데이터를 추가만 하고 별도로 전송한다고 생각하면 된다.)

      socket_.async_send_to(boost::asio::buffer(*message), remote_endpoint_,
          boost::bind(&udp_server::handle_send, this, message,
            boost::asio::placeholders::error,
            boost::asio::placeholders::bytes_transferred));


비동기 작업이 시작할 때, boost::bind()를 사용하는 경우라면 핸들러의 파라미터 목록과 일치하는 인수만 지정해야 한다. 이 프로그램에서 두 개의 인수 대체자(placeholder)는 (boost::asio::placeholders::error와 boost::asio::placeholders::bytes_transferred) 모두 제거되었을 수 있다.

다음 클라이언트 요청 수신을 시작한다.

      start_receive();


이제 클라이언트 요청에 대한 추가적인 작업(전송 결과 처리)은 handler_send()의 책임이다.

    }
  }


서비스 요청이 완료(클라이언트로 데이터 전송이 완료)된 후 handler_send() 함수가 호출된다.

  void handle_send(boost::shared_ptr<std::string> /*message*/,
      const boost::system::error_code& /*error*/,
      std::size_t /*bytes_transferred*/)
  {
  }

  udp::socket socket_;
  udp::endpoint remote_endpoint_;
  boost::array<char, 1> recv_buffer_;
};


전체 소스 보기

돌아가기: 튜토리얼 페이지

이전: Daytime.5 - 동기식 UDP daytime 서버
이후: Daytime.7 - 결합된 TCP/UDP 비동기식 서버

원본 링크

728x90
반응형