2008-02-09
boost::asio iostream
문자열 기반의 네트워크 입출력 프로그래밍을 해야 한다면, ASIO 의 iostream 을 사용하면 간단히 해결된다.
boost::asio::io_service 같이 모호한 객체 선언도 필요없고, 연결 관리나 버퍼링 같은 개념도 적당히 무시할 수 있어서, 예외 처리만 잘 한다면 원격 로그라든지 XML RPC 클라이언트 같은 곳에 써먹을 수 있을 것 같다.
만약 복잡한 문자열 조작이 필요하다면 boost::string_algo 정도면 충분하고, 정규식이 필요하면 boost::regexp 을 가져다 사용하면 될 듯하다.
// 문자열 기반의 네트워크 입출력 스트림
BOOST_AUTO_TEST_CASE( test_iostream )
{
string http_request =
"GET / HTTP/1.0\r\n"
"Host: reiot.cafe24.com\r\n\r\n";
string expected_http_response[] = { "HTTP/1.0 200 OK", "HTTP/1.1 200 OK" };
{
tcp::iostream io_("reiot.cafe24.com","http");
io_ << http_request << flush; // or io_.flush();
vector<string> http_response;
while ( !io_.eof() )
{
string line;
getline(io_,line);
http_response.push_back(line);
}
BOOST_CHECK_EQUAL( boost::trim_copy(http_response[0]), expected_http_response[1] );
io_.close();
}
{
string host = "www.google.co.kr";
tcp::iostream io_(host,"http");
io_ << "GET / HTTP/" << 1 << "." << 0 << endl
<< "Host: " << host << endl << endl
<< flush; // or io_.flush();
vector<string> http_response;
while ( !io_.eof() )
{
string line;
getline(io_,line);
http_response.push_back(line);
}
BOOST_CHECK_EQUAL( boost::trim_copy(http_response[0]), expected_http_response[0] );
}
{
tcp::iostream io_("www.naver.com","http");
io_ << "GET / HTTP/1.0" << endl
<< "Host: www.naver.com" << endl
<< endl
<< flush; // or io_.flush();
stringstream response;
while ( !io_.eof() )
{
char ch = io_.get();
response << ch;
}
string line;
getline(response,line);
BOOST_CHECK_EQUAL( boost::trim_copy(line), expected_http_response[1] );
}
{
tcp::iostream io_("clien.career.co.kr","http");
io_ << "GET / HTTP/1.0" << endl
<< "Host: clien.career.co.kr" << endl
<< endl
<< flush; // or io_.flush();
stringstream response;
while ( !io_.eof() )
{
char buf[128];
io_.read(buf,127);
size_t nread = io_.gcount();
if ( nread > 0 )
{
buf[nread] = 0;
response << buf;
}
}
string line;
getline(response,line);
BOOST_CHECK_EQUAL( boost::trim_copy(line), expected_http_response[1] );
}
}