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 비동기식 서버
원본 링크
'Boost C++ Libraries > Boost.Asio' 카테고리의 다른 글
Boost.Asio 튜토리얼 - Daytime.7 - 결합된 TCP/UDP 비동기식 서버 (0) | 2020.12.17 |
---|---|
Boost.Asio 튜토리얼 - Daytime.6 소스 (0) | 2020.12.17 |
Boost.Asio 튜토리얼 - Daytime.5 소스 (0) | 2020.12.17 |
Boost.Asio 튜토리얼 - Daytime.5 - 동기식 UDP daytime 서버 (0) | 2020.12.17 |
Boost.Asio 튜토리얼 - Daytime.4 소스 (0) | 2020.12.17 |