// // // // // Lab. Calcolo II - Esempio di codice // // // // // // // // Example code: Boost::asio HTTP client example code. // (20160829 francesco.prelz@mi.infn.it) #include <iostream> #include <memory> #include <string> #include <sstream> #include <functional> #include <boost/asio.hpp> #include "TApplication.h" #include "TASImage.h" typedef boost::asio::buffers_iterator<boost::asio::streambuf::const_buffers_type> stbuf_it; int main(int argc, char *argv[]) { if (argc < 2) { std::cerr << "Usage: " << argv[0] << " <HTTP server name> [service/port]" << std::endl; return 1; } std::string service("http"); if (argc > 2) service = argv[2]; TApplication theApp("Async I/O Example", &argc, argv); boost::asio::io_service io_service; using boost::asio::ip::tcp; tcp::resolver resolver(io_service); tcp::resolver::query query(argv[1], service); tcp::socket socket(io_service); boost::asio::streambuf buffer; TASImage image; resolver.async_resolve(query, [&](const boost::system::error_code& error, tcp::resolver::iterator iterator) { if (error) { std::cerr << "Error from boost::asio::ip::tcp::resolver::async_resolve: " << error.message() << std::endl; exit(1); } else { tcp::resolver::iterator end; boost::asio::async_connect(socket, iterator, end, [&](const boost::system::error_code& error, tcp::resolver::iterator iterator) { if (error) { std::cerr << "Error from boost::asio::ip::tcp::socket:async_connect: " << error.message() << std::endl; exit(1); } else { std::string msg("GET /\r\n"); socket.send(boost::asio::buffer(msg,msg.length())); boost::asio::async_read_until(socket, buffer, // Need to create a std::function here as the 'MatchCondition' // argument to async_read_until is tested via // boost::asio::is_function<T> in struct // boost::asio::is_match_condition, and this returns false on // closures as of boost v1_55. std::function<std::pair<stbuf_it, bool>(stbuf_it begin, stbuf_it end)> ( [&socket] (stbuf_it begin, stbuf_it end) { bool result = socket.is_open(); return std::make_pair(end, !result); }), [&](const boost::system::error_code& error, std::size_t size) { // Do something with the data std::istream is(&buffer); std::string s; while (is) { std::getline(is,s); if (s.find("Content-Type: image/png") == 0) { // Discard CRLF after Content-Type. std::getline(is,s); int img_size = boost::asio::buffer_size(buffer.data()); // C++14: auto img_data = std::make_unique<unsigned char[]>(img_size); char img_data[img_size]; is.read(img_data, img_size); char *img_start = &(img_data[0]); image.SetImageBuffer(&img_start, TImage::kPng); image.Draw(); } } } ); } } ); } } ); io_service.run(); std::cout << "*** Exit the program by selecting Quit from the File menu ***" << std::endl; theApp.Run(kTRUE); return 0; }