2009년 4월 14일 화요일

boost::asio 로 만들어본 간단한 콘솔 서버 ( async_read_until 사용예 )

서버를 짜다보면 간단한 제어 인터페이스를 노출할 경우가 많은데 보통 웹을 붙이거나 shell 을 흉내낸다. 이하는 asio 로 간단히 shell 흉내를 내는 코드를 만들어본것.

그냥 시간이 남아 간단히 만들어본건데 async_read_until 때문에 조금 고생했다.
이놈이 받는 버퍼는 다른 async 류 함수들과 달리 streambuf 더라.
나는 평소 C++ 을 쓰더라도 stream 쪽은 전혀 쓰질 않아서 이쪽은 하나도 모르는데.. 그래서 좀 애먹었다. 급한대로 streambuf 로부터 한글자씩 꺼내서 처리해봤는데 이건 좀 아닌거 같고 좀더 나은 방법을 뒤져봐야겠다.


이하는 main 을 담고있는 코드.
한줄을 받아서 한줄을 내놓는 최소한의 로직만 담고있는 클래스 echo 를 정의하고 이놈으로 console<echo> 인스턴스를 만들어 io_service 에 붙였다. 당연히 그냥 asio 공부하려고 만들어본 코드니 제구실하기엔 부족한 코드.

main.cpp..


아래는 console, session 을 담고있는 코드
console<T> 는 그냥 acceptor 라고 보면 된다. 특정 포트로 tcp 받아서 session<T> 를 까주는 놈. session<T> 는.. 결국 session<echo> 로 인스턴스가 만들어지는데 echo 가 가진 함수를 부르기 위한 소켓관련 작업들을 해주는 놈이다.

console.hpp..


이건 include 모음집. 네임스페이스 처리가 짱나서 하나에 몰아두고 쓰는게 좋지.

boostasio.hpp..



음.
좀더 뒤져서 asio::streambuf 에서 값을 꺼내는 방법을 하나 더 찾았다.
        asio::const_buffer data = buf_.data();
        const char* b = asio::buffer_cast<const char*>(data);
        const char* e = b + readed;
뭐 대략 이런식인데 이것도 통쾌한 방법은 아닌거 같다. 문서상 그리고 메일링에서도 istream 을 통해 꺼내오는것을 권장하는거 같은데.. iostream 쪽 코드는 영 손대기 그렇구만..
그리고 이런식으로 뽑아쓸경우 consume 으로 버퍼 비워주는것도 잊지말자.


추가.
ReadHandler 같은경우 error 와 readed 를 인자로 받는데 나는 error 나면 readed 무시하고 바로 에러를 내도록 했지만 경우에 따라 readed 를 먼저 처리하고 error 확인해야 할때도 있을거 같은데.. 이건 나중에 asio 를 정말 쓰게되면 다시 만날 문제겠지.






댓글 없음: