라인 기반 작업 (Line-Based Operations)
일반적으로 사용되는 많은 인터넷 프로토콜은 라인 기반이며, 이는 문자 시퀀스 "\r\n"로 구분되는 프로토콜 요소를 가지고 있다는 것을 의미한다. 예로 HTTP, SMTP 그리고 FTP 등이 있다. 구분 기호를 사용하는 다른 프로토콜뿐만 아니라 라인 기반 프로토콜의 구현을 보다 쉽게 접근하기 위해서, Boost.Asio는 read_until()와 async_read_until() 함수를 포함하고 있다.
다음 예제는 클라이언트의 HTTP 요청의 첫 번째 라인을 수신하는 위해 HTTP 서버에서 async_read_until()을 사용하는 방법을 보여준다:
class http_connection { ... void start() { boost::asio::async_read_until(socket_, data_, "\r\n", boost::bind(&http_connection::handle_request_line, this, _1)); } void handle_request_line(boost::system::error_code ec) { if (!ec) { std::string method, uri, version; char sp1, sp2, cr, lf; std::istream is(&data_); is.unsetf(std::ios_base::skipws); is >> method >> sp1 >> uri >> sp2 >> version >> cr >> lf; ... } } ... boost::asio::ip::tcp::socket socket_; boost::asio::streambuf data_; };
streambuf 데이터 멤버는 소켓에서 읽은 데이터(구분 기호를 검색하기 이전 데이터)를 저장하는 장소 역할을 한다. 구분 기호 뒤에 추가 데이터가 있을 수 있다는 점을 명심해야 한다. 이 추가 데이터는 streambuf에 남겨두어야 한다. 그래서 read_until()나 async_read_until()의 후속 호출에서 검사 될 수 있다.
구분 기호는 단일 char, std::string 또는 boost::regex로 지정될 수 있다. read_until()와 async_read_until() 함수에는 일치 조건(match condition)이라는 사용자 정의 함수 객체를 허용하는 오버로드도 포함된다. 예를 들어 공백이 발생할 때까지 streambuf로 데이터를 읽으려면 다음을 수행한다:
typedef boost::asio::buffers_iterator< boost::asio::streambuf::const_buffers_type> iterator; std::pair<iterator, bool> match_whitespace(iterator begin, iterator end) { iterator i = begin; while (i != end) if (std::isspace(*i++)) return std::make_pair(i, true); return std::make_pair(i, false); } ... boost::asio::streambuf b; boost::asio::read_until(s, b, match_whitespace);
일치하는 문자를 찾을 때까지 streambuf로 데이터를 읽으려면 다음을 수행한다:
class match_char { public: explicit match_char(char c) : c_(c) {} template <typename Iterator> std::pair<Iterator, bool> operator()( Iterator begin, Iterator end) const { Iterator i = begin; while (i != end) if (c_ == *i++) return std::make_pair(i, true); return std::make_pair(i, false); } private: char c_; }; namespace boost { namespace asio { template <> struct is_match_condition<match_char> : public boost::true_type {}; } } // namespace boost::asio ... boost::asio::streambuf b; boost::asio::read_until(s, b, match_char('a'));
is_match_condition<> 유형 특성은 함수 및 중첩된 result_type typedef가 있는 함수 개체에 대해 true로 자동 평가한다. 다른 유형의 경우 위와 같이 특성을 명시적으로 특수화(specialised) 해야 한다.
더 보기
async_read_until(), is_match_condition, read_until(), streambuf, HTTP client example.
'Boost C++ Libraries > Boost.Asio' 카테고리의 다른 글
Boost.Asio 개요 - 핵심 개념 및 기능 - 핸들러 추적 (0) | 2020.12.09 |
---|---|
Boost.Asio 개요 - 핵심 개념 및 기능 - 사용자 지정 메모리 할당 (0) | 2020.12.08 |
Boost.Asio 개요 - 핵심 개념 및 기능 - Reactor 스타일 작업 (0) | 2020.12.08 |
Boost.Asio 개요 - 핵심 개념 및 기능 - 스트림, 짧은 읽기와 짧은 쓰기 (0) | 2020.12.08 |
Boost.Asio 개요 - 핵심 개념 및 기능 - 버퍼 (0) | 2020.12.07 |