User Tools

Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

cpp:wclient [2019-05-28 15:26] (current)
Line 1: Line 1:
 +=====Sample async boost web clent=====
 +
 +<code c++ wclient.c>​
 +/*
 + * wclient.cpp
 + *
 + * Copyright 2004-2019 Oleg Borodin <​borodin@unix7.org>​
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License as published by
 + * the Free Software Foundation; either version 2 of the License, or
 + * (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ​ See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 + * MA 02110-1301, USA.
 + *
 + */
 +
 +#include <​iostream>​
 +#include <​istream>​
 +#include <​ostream>​
 +#include <​string>​
 +#include <​regex>​
 +
 +#include <​boost/​asio.hpp>​
 +#include <​boost/​bind.hpp>​
 +
 +using namespace boost::​asio;​
 +
 +class wclient {
 +  public:
 +
 +    boost::​asio::​streambuf request_buffer;​
 +    boost::​asio::​streambuf response_buffer;​
 +
 +    std::string hostname = "​localhost";​
 +    std::string url = "/";​
 +    std::string port = "​http";​
 +
 +    wclient(std::​string _hostname, std::string _url) : hostname(_hostname),​ url(_url) {
 +        /* nope */
 +    }
 +
 +    void run() {
 +        boost::​asio::​io_service io_service;
 +        try {
 +
 +            std::cout << "# try http get host " << hostname << " port " << port << "​\n";​
 +            ip::​tcp::​resolver resolver(io_service);​
 +            ip::​tcp::​resolver::​query query(hostname,​ "​http"​);​
 +            ip::​tcp::​resolver::​iterator endpoint_iterator = resolver.resolve(query);​
 +
 +            ip::​tcp::​socket socket(io_service);​
 +
 +            std::​ostream request_stream(&​request_buffer);​
 +            request_stream << "GET "<<​ url <<"​ HTTP/​1.0\r\n";​
 +            request_stream << "Host: " << hostname << "​\r\n";​
 +            request_stream << "​Accept:​ */​*\r\n";​
 +            request_stream << "​Connection:​ close\r\n\r\n";​
 +
 +            std::cout << "# try async connect\n";​
 +            boost::​asio::​async_connect(
 +                socket,
 +                endpoint_iterator,​
 +                boost::​bind(
 +                    &​wclient::​handle_connect,​
 +                    this,
 +                    boost::​asio::​placeholders::​error,​
 +                    &socket
 +                )
 +            );
 +            io_service.run();​
 +        } catch (std::​exception&​ e) {
 +            std::cout << "# exception: " << e.what() << "​\n";​
 +        }
 +    }
 +    void handle_connect(const boost::​system::​error_code&​ err, ip::​tcp::​socket *socket) {
 +        if (err) {
 +            std::cout << "# error while connect action: " << err.message() << "​\n";​
 +            return;
 +        }
 +        std::cout << "# try handle connect action\n";​
 +        boost::​asio::​async_write(
 +            *socket,
 +            request_buffer,​
 +            boost::​bind(
 +                &​wclient::​handle_write,​
 +                this,
 +                boost::​asio::​placeholders::​error,​
 +                socket
 +            )
 +        );
 +    }
 +    void handle_write(const boost::​system::​error_code&​ err, ip::​tcp::​socket *socket) {
 +        if (err) {
 +            std::cout << "# error while write action: " << err.message() << "​\n";​
 +            return;
 +        }
 +        std::cout << "# try handle write action\n";​
 +        boost::​asio::​async_read_until(
 +            *socket,
 +            response_buffer,​
 +            "​\r\n",​
 +            boost::​bind(
 +                &​wclient::​handle_read,​
 +                this,
 +                boost::​asio::​placeholders::​error,​
 +                socket
 +            )
 +        );
 +    }
 +    void handle_read(const boost::​system::​error_code&​ err, ip::​tcp::​socket *socket) {
 +        if (err) {
 +            std::cout << "# error while read action: " << err.message() << "​\n";​
 +            return;
 +        }
 +        std::cout << "# try handle read action\n";​
 +        std::​istream response_stream(&​response_buffer);​
 +
 +        std::regex re("​^HTTP[/​]1.[01]"​);​
 +        std::smatch ma;
 +
 +        std::string header;
 +        while (std::​getline(response_stream,​ header) && header != "​\r"​) {
 +            std::​regex_search(header,​ ma, re);
 +            if (ma.size() > 0) {
 +                std::cout << "# result: " << header << "​\n";​
 +            }
 +        }
 +        std::cout << "# the end\n";​
 +    }
 +};
 +
 +int main(int argc, char* argv[]) {
 +    wclient wclient("​wiki.unix7.org",​ "/"​);​
 +    wclient.run();​
 +    return 0;
 +}
 +</​code>​
 +
 +====Out====
 +
 +<​file>​
 +$ c++ -Wall -I/​usr/​local/​include -pthread -o wclient wclient.cpp ​ \
 +   ​-L/​usr/​local/​lib -lboost_system -lboost_iostreams ​
 +$ ./wclient
 +# try http get host wiki.unix7.org port http
 +# try async connect
 +# try handle connect action
 +# try handle write action
 +# try handle read action
 +# result: HTTP/1.1 200 OK
 +# the end
 +</​file>​
 +