Daytime.1 - A synchronous TCP daytime client

Programming/Boost asio 2015.04.13 01:17

다음 내용에 기반함


Introduction to Sockets

The tutorial programs in this section show how to use asio to develop simple client and server programs. These tutorial programs are based around the daytimeprotocol, which supports both TCP and UDP.

The first three tutorial programs implement the daytime protocol using TCP.


이번 튜토리얼에서는 TCP 클라이언트를 만드는데 어떻게 이용 할 수 있을지 소개한다.

먼저 필요한 헤더파일들을 include 하는 것으로 시작한다.
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>

이 응용프로그램은 daytime 서비스에 접근하는것이며, 따라서 유저가 서버를 특정할 필요가 있다.

using boost::asio::ip::tcp; int main(int argc, char* argv[]) { try { if (argc != 2) { std::cerr << "Usage: client <host>" << std::endl; return 1; }


asio 를 이용하는 모든 프로그램들은 적어도 하나이상의 io_service 객체를 필요로한다. 
    boost::asio::io_service io_service;


파라미터에 지정된 서버 이름을 TCP endpoint 로 변환할 필요가 있는데, 이는 ip::tcp::resolver 객체를 통한다.

  tcp::resolver resolver(io_service);


resolver 는 쿼리 객체를 받아 이를 endpoint 의 리스트로 변환한다. 쿼리이름을 서버이름을 이용하여 생성할 것이며, 이 서비스의 이름은 "daytime" 이다.

리스트는  ip::tcp::resolver::iterator 타입으로 리턴된다. (ip::tcp::resolver::iterator 의 기본 생성자를 통해 생성된 객체는 end iterator 로 사용 될 수 있다)

   tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);


이제 소켓을 생성하고 연결할 차례다. 

얻어진 리스트는 IPv4 와 IPv6 를 모두 포함할 수도 있으므로 동작하는 것을 찾기 위해 각각의 주소들에 대해 시도해야한다. 

이런 사용이, 클라이언트 프로그램이 특정 IP 주소체계와 독립적으로 프로그램을 구성할 수 있게 해준다. 

boost::asio::connect() 함수는 자동적으로 이를 수행해준다.

    tcp::socket socket(io_service);
    boost::asio::connect(socket, endpoint_iterator);


이제 연결이 수립되었다. daytime 서비스의 응답만을 기다리면 된다.


boost::array 를 전달받은 데이터를 저장하는데 사용하도록 하자. boost::asio::buffer() 함수는 자동적으로 배열의 사이즈를 결정해주어 버퍼 오버런이 발생하지 않게 도와준다. boost::array 대신에, char[] 나 std::vector 도 사용할 수 있다.

 for (;;)
    {
      boost::array<char, 128> buf;
      boost::system::error_code error;

      size_t len = socket.read_some(boost::asio::buffer(buf), error);


서버가 연결을 종료했을때, ip::tcp::socket::read_some 함수는 boost::asio::error::eof 에러와 함께 종료될 것이며, 이때 루프를 빠져나가면 된다.

if (error == boost::asio::error::eof) break; // Connection closed cleanly by peer. else if (error) throw boost::system::system_error(error); // Some other error. std::cout.write(buf.data(), len); }


마지막으로, thrown 된 예외를 처리하면 된다. 


full source code




main 


실행결과 




저작자 표시 비영리 변경 금지
신고

Tutorial 3. Binding arguments to a handler

Programming/Boost asio 2015.03.15 16:22

다음에 기반함


http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/tutorial/tuttimer3.html


이제 AsyncTimer 를 수정해서 1초에 한번씩 실행 되도록 수정하겠다고 한다. 


타이머 시간을 수정하고 (기존 5초), 다시 내부에서 새로운 비동기 wait 을 호출하면 된다.

즉, 핸들러내부에서 타이머 객체에 접근하는 것이 필요하다.

2 개의 인자를 추가한다. 


boost::asio::deadline_timer* t (deadline timer 는 reference 가 불가능하게 되어있다.) 와 int* count 이다. (최종 count 값을 리턴받으려면 pointer 로. )


count 는 6번째로 타이머가 실행되었을 때는 타이머를 다시 실행시키지 않도록 하기 위해 추가한 인자다. 

io_service 에는 stop 과 같은 명시적으로 중지를 요청하는 호출이 없고, 대신 'work' 가 없을때 함수가 종료된다는 것을 상기하자.

카운트가 5에 도달하면 새로운 async_wait 을 호출하지 않는 것으로 io_service 는 work 가 소진되고 동작이 중지 될 것이다.


그리고 타이머의 만료시간을 이전 만료시간으로부터 1초 뒤로 지정한다. 이전 시간에서 계산하는 것으로 핸들러를 처리하는데 소요된 시간으로 인해 지연되지 않도록 한다.


periodTimer




메인함수. 호출부



저작자 표시 비영리 변경 금지
신고

'Programming > Boost asio' 카테고리의 다른 글

Tutorial 5. Synchronising handlers in multithreaded programs  (0) 2015.04.11
Tutorial 4. member function handler  (0) 2015.03.17
Tutorial 3. Binding arguments to a handler  (0) 2015.03.15
Tutorial 2. async_timer  (0) 2015.03.14
Tutorial 1. sync_timer  (0) 2015.02.04
0. 소개  (0) 2015.02.02

Tutorial 2. async_timer

Programming/Boost asio 2015.03.14 16:14

다음 내용에 기반함


http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/tutorial/tuttimer2.html


이전 시간에 deadline_timer 를 이용하여 5초 대기후 메시지를 출력, 종료하는 프로그램을 다뤄봤다. 

sync 함수를 호출했기 때문에 이를 호출한 스레드는 다른 작업을 수행 할 수 없었다.


이제 async 하게 동작하여 호출한 스레드가 다른 작업을 수행할 수 있도록 해보자.


사용했던 함수를 async_wait 으로 변경한것, 그리고 run() 을 호출한 내용이 다르다. 


io_service::run() 은 지정한 work 를 수행하도록 명령한다. 동작이 완료되면 work 에 함께 지정된 핸들러(콜백)를 호출해주는데, 

이때 핸들러는 run() 을 호출한 스레드에서만 호출이 된다. 즉, 스레드풀등에서 run() 을 호출하면 해당 스레드풀에서 핸들러가 호출 되게 하는 방식으로 사용할 수 있다.


수정한 내용이 많지 않기 때문에, 코드를 보면 간단하게 이해가 가능하다.


1. io_service 와 io_object 를 생성하고

2. aync_wait 이라는 work 를 지정하고

3. run() 수행


튜토리얼과 다소 차이가 있는 부분은, 프로젝트의 관리 편의상 클래스를 지정했는데 이에 따라 handler 지정시 bind 로 전달했다.


Class AsyncTimer



int main()



저작자 표시 비영리 변경 금지
신고

'Programming > Boost asio' 카테고리의 다른 글

Tutorial 5. Synchronising handlers in multithreaded programs  (0) 2015.04.11
Tutorial 4. member function handler  (0) 2015.03.17
Tutorial 3. Binding arguments to a handler  (0) 2015.03.15
Tutorial 2. async_timer  (0) 2015.03.14
Tutorial 1. sync_timer  (0) 2015.02.04
0. 소개  (0) 2015.02.02