10 C++ Boost ASIO网路通信库 TCP/UDP,HTTP

时间:2022-09-09 11:50:34
 
tcp 同步服务器,显示服务器端时间
tcp 同步服务器,提供多种选择
多线程的tcp 同步服务器
tcp 同步客户端
boost 域名地址解析

tcp异步服务器
tcp 异步客户端

UDP同步服务器
UDP同步客户端

UDP异步服务器
UDP异步客户端

HTTP同步客户端
HTTP异步客户端

同步实验:
异步实验
多线程异步实验


10 C++ Boost ASIO网路通信库 TCP/UDP,HTTP

10 C++ Boost ASIO网路通信库 TCP/UDP,HTTP

10 C++ Boost ASIO网路通信库 TCP/UDP,HTTP



 

tcp 同步服务器,显示服务器端时间

chunli@Linux:~/boost$ cat main.cpp #include <ctime>#include <iostream>#include <string>#include <boost/asio.hpp>using boost::asio::ip::tcp;std::string make_daytime_string(){using namespace std; // For time_t, time and ctime;time_t now = time(0);return ctime(&now);}int main(){try{boost::asio::io_service io_service;tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 8080));for (;;){tcp::socket socket(io_service);acceptor.accept(socket);std::string message = make_daytime_string();boost::system::error_code ignored_error;boost::asio::write(socket, boost::asio::buffer(message), ignored_error);}}catch (std::exception& e){std::cerr << e.what() << std::endl;}return 0;}编译运行:chunli@Linux:~/boost$ g++ main.cpp -l boost_system && ./a.out 客户端来访问:chunli@Linux:~$ netstat -tnlpProto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program nametcp        0      0 127.0.1.1:53            0.0.0.0:*               LISTEN      -               tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -               tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      -               tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      4100/a.out      tcp6       0      0 :::22                   :::*                    LISTEN      -               tcp6       0      0 ::1:631                 :::*                    LISTEN      -               tcp6       0      0 :::80                   :::*                    LISTEN      -               chunli@Linux:~$ chunli@Linux:~$ nc 127.0.0.1 8080Tue Dec 27 13:06:53 2016chunli@Linux:~$ nc 127.0.0.1 8080Tue Dec 27 13:06:55 2016chunli@Linux:~$ nc 127.0.0.1 8080Tue Dec 27 13:06:55 2016chunli@Linux:~$



tcp 同步服务器,提供多种选择

chunli@Linux:~/boost$ cat main.cpp #include <iostream>#include <fstream>#include <sstream>#include <string>#include <boost/asio.hpp>using namespace std;using boost::asio::ip::tcp;const char serviceList[] = "        Services          \n""**************************\n""[1] Get current time.     \n""[2] Who's online.         \n""[3] Get system info.      \n""**************************\n""Please pick a service[1-3]: ";void getResult(const string& cmdPrefix, const char* outputFile, string& res) {// cmd == "w > who"string cmd(cmdPrefix + outputFile);system(cmd.c_str());ifstream fin;fin.open(outputFile);if (fin) {ostringstream os;os << fin.rdbuf();res = os.str();}if (fin.is_open()) {fin.close();}}string getServiceContent(const int& select) {string res;switch (select) {case 1: {time_t t = time(0);res = ctime(&t);break;}case 2:getResult("w > ", "who", res);break;case 3:getResult("uname -a > ", "uname", res);break;default:res = "Sorry, no such service.\n";break;}return res;}int main() {try {boost::asio::io_service io_service; // #1tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 8868)); // #2while(1){tcp::socket socket(io_service); acceptor.accept(socket); boost::system::error_code ignored_error;boost::asio::write(socket, boost::asio::buffer(serviceList),ignored_error);char selection[20];size_t n = socket.read_some(boost::asio::buffer(selection),ignored_error);string response = getServiceContent(atoi(selection));boost::asio::write(socket, boost::asio::buffer(response),boost::asio::transfer_all(), ignored_error);}} catch (std::exception& e) {std::cerr << e.what() << std::endl;}return 0;}编译运行:chunli@Linux:~/boost$ g++ main.cpp -l boost_system && ./a.out客户端来验证:chunli@Linux:~/boost$ nc 127.0.0.1 8868        Services          **************************[1] Get current time.     [2] Who's online.         [3] Get system info.      **************************Please pick a service[1-3]: 1Tue Dec 27 13:41:51 2016chunli@Linux:~/boost$ nc 127.0.0.1 8868        Services          **************************[1] Get current time.     [2] Who's online.         [3] Get system info.      **************************Please pick a service[1-3]: 2 13:41:54 up  3:39,  4 users,  load average: 0.07, 0.03, 0.00USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHATchunli   pts/6    chunli-pc        10:03    1:22   3.69s  3.37s vim main.cppchunli   pts/10   chunli-pc        11:58    1:14   0.89s  0.00s sh -c w > whochunli   :0       :0               12:41   ?xdm?   4:25   0.44s init --userchunli   pts/0    chunli-pc        13:06    2.00s  0.33s  0.00s nc 127.0.0.1 8868chunli@Linux:~/boost$ nc 127.0.0.1 8868        Services          **************************[1] Get current time.     [2] Who's online.         [3] Get system info.      **************************Please pick a service[1-3]: 3Linux Linux 4.4.0-31-generic #50~14.04.1-Ubuntu SMP Wed Jul 13 01:07:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linuxchunli@Linux:~/boost$ nc 127.0.0.1 8868        Services          **************************[1] Get current time.     [2] Who's online.         [3] Get system info.      **************************Please pick a service[1-3]: 4Sorry, no such service.chunli@Linux:~/boost$


10 C++ Boost ASIO网路通信库 TCP/UDP,HTTP



多线程的tcp 同步服务器

chunli@Linux:~/boost$ cat main.cpp #include <iostream>#include <fstream>#include <sstream>#include <boost/asio.hpp>#include <boost/shared_ptr.hpp>#include <boost/bind.hpp>#include <boost/thread.hpp>using namespace std;using boost::asio::ip::tcp;const char serviceList[] = "\n\t       Services\n""\t**************************\n""\t[1] Get current time.\n""\t[2] Who's online.\n""\t[3] Get system info.\n""\t**************************\n\n""Please pick a service[1-3]: ";void getResult(const string& cmdPrefix, const char* outputFile, string& res) {// cmd == "w > who"string cmd(cmdPrefix + outputFile);system(cmd.c_str());ifstream fin;fin.open(outputFile);if (fin) {ostringstream os;os << fin.rdbuf();res = os.str();}if (fin.is_open()) {fin.close();}}string getServiceContent(const int& select) {string res;switch (select) {case 1: {time_t t = time(0);res = ctime(&t);break;}case 2:getResult("w > ", "who", res);break;case 3:getResult("uname -a > ", "uname", res);break;default:res = "Sorry, no such service.\n";break;}return res;}typedef boost::shared_ptr<tcp::socket> SocketPtr;void handleIo(SocketPtr socket) {// 1, send service list to clientboost::system::error_code ignored_error;boost::asio::write(*socket, boost::asio::buffer(serviceList),boost::asio::transfer_all(), ignored_error);// 2, receive selection from clientchar selection[20];size_t n = socket->read_some(boost::asio::buffer(selection), ignored_error);// 3, send responsestring response = getServiceContent(atoi(selection));boost::asio::write(*socket, boost::asio::buffer(response),boost::asio::transfer_all(), ignored_error);socket->close();//主动关闭socket}int main() {try {boost::asio::io_service io_service; // #1tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 8868)); // #2boost::thread_group grp;for (;;) {SocketPtr socket(new tcp::socket(io_service)); // #3acceptor.accept(*socket); // #4grp.create_thread(boost::bind(handleIo, socket));} // #6} catch (std::exception& e) {std::cerr << e.what() << std::endl;}return 0;}chunli@Linux:~/boost$ g++ main.cpp -l boost_system -l boost_thread && ./a.out多个客户端验证:不存在阻塞问题chunli@Linux:~/boost$ nc 127.0.0.1 8868       Services**************************[1] Get current time.[2] Who's online.[3] Get system info.**************************Please pick a service[1-3]: --------------------------------chunli@Linux:~$ chunli@Linux:~$ nc 127.0.0.1 8868       Services**************************[1] Get current time.[2] Who's online.[3] Get system info.**************************Please pick a service[1-3]:




tcp 同步客户端

chunli@Linux:~/boost$ cat client.cpp #include <iostream>#include <boost/asio.hpp>using namespace std;using boost::asio::ip::tcp;int main(int argc, char* argv[]) {try {// 1, 创建io_service对象boost::asio::io_service io_service;// 2, 创建resolver对象关联到io_service对象tcp::resolver resolver(io_service);// 3, 创建一个查询对象tcp::resolver::query query("localhost", "8868");// 4, 用resolver对象和查询对象获取可用服务器地址tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);tcp::resolver::iterator end;// 5, 创建tcp::socket对象,关联到io_servicetcp::socket socket(io_service);// 6, socket对象发起到服务器端的同步连接操作boost::system::error_code error = boost::asio::error::host_not_found;while (error && endpoint_iterator != end) {socket.close();socket.connect(*endpoint_iterator++, error);}if (error) // 如果没有一个地址能连接成功,则抛出异常throw boost::system::system_error(error);// 7, 一系列 同步read()和write()char buf[512];// receive service list from server//        size_t len = socket.read_some(boost::asio::buffer(buf), error);//        size_t len = socket.receive(boost::asio::buffer(buf), 0, error);size_t len = boost::asio::read(socket, boost::asio::buffer(buf),boost::asio::transfer_at_least(1), error);buf[len] = '\0';cout << buf;string selection;cin >> selection;// send selection to server//        boost::asio::write(socket, boost::asio::buffer(selection),//                boost::asio::transfer_all(), error);//        socket.write_some(boost::asio::buffer(selection,selection.size()), error);socket.send(boost::asio::buffer(selection,selection.size()),0, error);// receive response from serverlen = socket.read_some(boost::asio::buffer(buf), error);buf[len] = '\0';cout << buf;} catch (std::exception& e) {std::cerr << e.what() << std::endl;}return 0;}chunli@Linux:~/boost$ g++ client.cpp -l boost_system -lpthread -o client && ./client       Services**************************[1] Get current time.[2] Who's online.[3] Get system info.**************************Please pick a service[1-3]:




boost 域名地址解析

chunli@Linux:~/boost$ cat client.cpp #include <iostream>#include <boost/asio.hpp>using namespace std;using boost::asio::ip::tcp;int main(int argc, char* argv[]) {    // 1, 创建io_service对象    boost::asio::io_service io_service;    // 2, 创建resolver对象关联到io_service对象    tcp::resolver resolver(io_service);    for (;;) {        try {            string host, port;            cin >> host >> port;            // 3, 创建一个查询对象            tcp::resolver::query query(host, port);            // 4, 用resolver对象和查询对象获取可用服务器地址            tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);            tcp::resolver::iterator end;            // 5, 创建tcp::socket对象,关联到io_service            tcp::socket socket(io_service);            // 6, socket对象发起到服务器端的同步连接操作            boost::system::error_code error =                    boost::asio::error::host_not_found;            while (endpoint_iterator != end) {                cout << endpoint_iterator->endpoint() << endl;                socket.close();                socket.connect(*endpoint_iterator++, error);            }            if (error) // 如果没有一个地址能连接成功,则抛出异常                throw boost::system::system_error(error);        } catch (std::exception& e) {            std::cerr << e.what() << std::endl;        }    }    return 0;}chunli@Linux:~/boost$ chunli@Linux:~/boost$ g++ client.cpp -l boost_system -lpthread -o client && ./clientwww.baidu.com 443115.239.210.27:443115.239.211.112:443www.taobao.com 80101.227.208.227:80101.227.208.226:80114.80.174.46:80222.73.134.63:80114.80.174.47:8051cto.com 80123.56.215.220:80



tcp异步服务器

chunli@Linux:~/boost$ cat main.cpp #include <iostream>#include <boost/asio.hpp>#include <boost/bind.hpp>#include <boost/shared_ptr.hpp>#include <boost/enable_shared_from_this.hpp>using namespace std;using boost::asio::ip::tcp;class Connection: public boost::enable_shared_from_this<Connection> {public:    Connection(boost::asio::io_service& service) :        sock(service) {    }    void start() {        //        sock.async_read_some(boost::asio::buffer(buf), boost::bind(        //                &Connection::handleRead, // #1        //                shared_from_this(), boost::asio::placeholders::error));        boost::asio::async_read(sock, boost::asio::buffer(buf),                boost::asio::transfer_at_least(1), boost::bind(                        &Connection::handleRead, // #1                        shared_from_this(), boost::asio::placeholders::error));    }    tcp::socket& getSocket() {        return sock;    }private:    void handleRead(const boost::system::error_code& error) {        if (!error) {            cout << "recv from: " << sock.remote_endpoint().address() << ":" << sock.remote_endpoint().port() << endl;            //            boost::asio::async_write(sock, boost::asio::buffer(buf),            //                    boost::bind(            //                            &Connection::handleWrite, // #2            //                            shared_from_this(),            //                            boost::asio::placeholders::error));            sock.async_write_some(boost::asio::buffer(buf),                    boost::bind(                            &Connection::handleWrite, // #2                            shared_from_this(),                            boost::asio::placeholders::error));        }    }    void handleWrite(const boost::system::error_code& error) {        if (!error) {            memset(buf, 0, 512); // 注意:重置buf            sock.async_read_some(boost::asio::buffer(buf), boost::bind(                    &Connection::handleRead, // #3                    shared_from_this(), boost::asio::placeholders::error));        }    }private:    tcp::socket sock;    char buf[512];};typedef boost::shared_ptr<Connection> ConnectionPtr;class Server {public:    Server(boost::asio::io_service& service) :        acceptor(service, tcp::endpoint(tcp::v4(), 8080)) {        start();    }private:    void start() {        ConnectionPtr conn(new Connection(acceptor.get_io_service()));        acceptor.async_accept(conn->getSocket(), boost::bind(                &Server::handleAccept, this, conn,                boost::asio::placeholders::error));    }    void handleAccept(ConnectionPtr con, const boost::system::error_code& error) {        if (!error) {            con->start();            start();        }    }private:    tcp::acceptor acceptor;};int main() {    try {        boost::asio::io_service service;        Server server(service);        service.run(); // 注意:与同步I/O不同,异步I/O需要调用run()    } catch (exception& e) {        cout << e.what() << endl;    }    return 0;}chunli@Linux:~/boost$ g++ main.cpp -l boost_system -l boost_thread && ./a.outchunli@Linux:~/boost$ nc 127.0.0.1 8080hellohellohello Worldhello World



tcp 异步客户端

chunli@Linux:~/boost$ cat client.cpp #include <iostream>#include <boost/asio.hpp>#include <boost/bind.hpp>using namespace std;using namespace boost::asio::ip;class Client {public:Client(boost::asio::io_service& service,tcp::resolver::iterator endpointIterator):sock(service){tcp::endpoint endpoint = *endpointIterator;sock.async_connect(endpoint, boost::bind(&Client::handleConnect, this,boost::asio::placeholders::error, ++endpointIterator));}private:void handleConnect(const boost::system::error_code& error,tcp::resolver::iterator endpointIterator) {if (!error) {memset(buf, 0, 512);cin.getline(buf, BUF_SIZE);boost::asio::async_write(sock,boost::asio::buffer(buf, strlen(buf)), boost::bind(&Client::handleWrite,this,boost::asio::placeholders::error));} else if (endpointIterator != tcp::resolver::iterator()) {sock.close();tcp::endpoint endpoint = *endpointIterator;sock.async_connect(endpoint, boost::bind(&Client::handleConnect,this, boost::asio::placeholders::error, ++endpointIterator));}}void handleRead(const boost::system::error_code& error) {if (!error) {cout << buf << endl; // print received messagememset(buf, 0, 512);cin.getline(buf, BUF_SIZE);boost::asio::async_write(sock,boost::asio::buffer(buf, strlen(buf)), boost::bind(&Client::handleWrite,this,boost::asio::placeholders::error));}}void handleWrite(const boost::system::error_code& error) {if (!error) {memset(buf, 0, 512); // 注意:重置bufsock.async_read_some(boost::asio::buffer(buf),boost::bind(&Client::handleRead, this,boost::asio::placeholders::error));}}private:tcp::socket sock;enum {BUF_SIZE = 512};char buf[BUF_SIZE];};int main() {try {boost::asio::io_service service;tcp::resolver resolver(service);tcp::resolver::query query("localhost", "8868");tcp::resolver::iterator iterator = resolver.resolve(query);tcp::endpoint addr(address::from_string("127.0.0.1"), 8868);Client client(service, iterator);service.run();} catch (std::exception& e) {std::cerr << "Exception: " << e.what() << "\n";}return 0;}chunli@Linux:~/boost$ g++ client.cpp -l boost_system -lpthread -o client && ./clienthellohellohahahaha



UDP同步服务器

chunli@Linux:~/boost$ cat server.cpp #include <iostream>#include <boost/asio.hpp>using namespace std;using boost::asio::ip::udp;int main() {    try {        boost::asio::io_service service; // #1        udp::socket socket(service, udp::endpoint(udp::v4(), 8868)); //#2        char buf[512];        for (;;) {            memset(buf, 0, 512);            udp::endpoint remoteEndpoint; // #3            boost::system::error_code error;            size_t len = socket.receive_from(boost::asio::buffer(buf),                    remoteEndpoint, 0, error);//#4            if (error && error != boost::asio::error::message_size)                throw boost::system::system_error(error);            boost::system::error_code ignoredError;            socket.send_to(boost::asio::buffer(buf, len), remoteEndpoint, 0,                    ignoredError); // #5        }    } catch (std::exception& e) {        std::cerr << e.what() << std::endl;    }    return 0;}chunli@Linux:~/boost$ g++ server.cpp -lboost_system -o S && ./Schunli@Linux:~$ netstat -unlpProto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program nameudp        0      0 0.0.0.0:631             0.0.0.0:*                           -               udp        0      0 0.0.0.0:8868            0.0.0.0:*                           2050/S          chunli@Linux:~$ nc -u 127.0.0.1 8868hellohello中国上海!中国上海!




UDP同步客户端

chunli@Linux:~/boost$ cat client.cpp #include <iostream>#include <boost/asio.hpp>using namespace std;using boost::asio::ip::udp;int main(int argc, char* argv[]) {try {boost::asio::io_service service; // #1udp::resolver resolver(service); // #2udp::resolver::query query(udp::v4(), "localhost", "8868"); // #3udp::endpoint receiverEndpoint = *resolver.resolve(query); // #4//        udp::socket socket(service);//        socket.open(udp::v4()); // #5//        udp::endpoint receiverEndpoint(boost::asio::ip::address::from_string("192.168.0.101"), 51179);udp::socket socket(service, udp::v4());// #5char buf[512];for (;;) {memset(buf, 0, 512);cin.getline(buf, 512);socket.send_to(boost::asio::buffer(buf, strlen(buf)),receiverEndpoint); // #6memset(buf, 0, 512);udp::endpoint senderEndpoint; // #7socket.receive_from(boost::asio::buffer(buf), senderEndpoint); // #8cout << buf << endl;}} catch (std::exception& e) {std::cerr << e.what() << std::endl;}return 0;}chunli@Linux:~/boost$ g++ client.cpp -lboost_system -pthread -o C && ./C中国上海!中国上海!Hello Boost asio!Hello Boost asio!





UDP异步服务器

chunli@Linux:~/boost$ cat server.cpp #include <iostream>#include <boost/asio.hpp>#include <boost/bind.hpp>using namespace std;using boost::asio::ip::udp;class Server {public:    Server(boost::asio::io_service& service) :        sock(service, udp::endpoint(udp::v4(), 8868)) {        start();    }private:    void start() {        memset(buf, 0, BUF_SIZE);        sock.async_receive_from(boost::asio::buffer(buf), remoteEndpoint,                boost::bind(&Server::handleReceive, this,                        boost::asio::placeholders::error,                        boost::asio::placeholders::bytes_transferred));    }    void handleReceive(const boost::system::error_code& error,            std::size_t bytes_transferred) {        if (!error || error == boost::asio::error::message_size) {            cout << remoteEndpoint << endl;            sock.async_send_to(boost::asio::buffer(buf, bytes_transferred),                    remoteEndpoint, boost::bind(&Server::handleSend, this,                            boost::asio::placeholders::error));            start();        }    }    void handleSend(const boost::system::error_code& /*error*/) {    }private:    udp::socket sock;    udp::endpoint remoteEndpoint;    enum {        BUF_SIZE = 512    };    char buf[BUF_SIZE];};int main() {    try {        boost::asio::io_service service;        Server server(service);        service.run(); // 注意:一定要调用 run()函数    } catch (std::exception& e) {        std::cerr << e.what() << std::endl;    }    return 0;}chunli@Linux:~/boost$ chunli@Linux:~/boost$ g++ server.cpp -lboost_system -o S && ./S127.0.0.1:36398127.0.0.1:36398





UDP异步客户端

chunli@Linux:~/boost$ cat client.cpp #include <iostream>#include <boost/asio.hpp>#include <boost/bind.hpp>using namespace std;using boost::asio::ip::udp;class Client {public:    Client(boost::asio::io_service& service, const udp::endpoint& remote) :        remoteEndpoint(remote), sock(service, udp::v4()) {        // sock.open(udp::v4());        start();    }private:    void start() {        memset(buf, 0, BUF_SIZE);        cin.getline(buf, BUF_SIZE);        sock.async_send_to(boost::asio::buffer(buf, strlen(buf)),                remoteEndpoint, boost::bind(&Client::handleSend, this,                        boost::asio::placeholders::error));    }    void handleSend(const boost::system::error_code& error) {        if (!error) {            memset(buf, 0, BUF_SIZE);            udp::endpoint local;            sock.async_receive_from(boost::asio::buffer(buf, BUF_SIZE), local,                    boost::bind(&Client::handleReceive, this,                            boost::asio::placeholders::error));        }    }    void handleReceive(const boost::system::error_code& error) {        if (!error) {            cout << buf << endl;            start();        }    }private:    udp::endpoint remoteEndpoint;    udp::socket sock;    enum {        BUF_SIZE = 512    };    char buf[BUF_SIZE];};int main() {    try {        boost::asio::io_service service;        udp::resolver resolver(service);        udp::resolver::query query(udp::v4(), "localhost", "8868");        udp::endpoint receiverEndpoint = *resolver.resolve(query);        cout << receiverEndpoint << endl;//        cout << receiverEndpoint.address().to_string() << endl;//        cout << receiverEndpoint.port() << endl;        Client c(service, receiverEndpoint);        service.run();    } catch (exception& e) {        cout << e.what() << endl;    }}chunli@Linux:~/boost$ g++ client.cpp -lboost_system -pthread -o C && ./C127.0.0.1:8868hahahaha中国上海中国上海



HTTP同步客户端

chunli@Linux:~/boost$ cat client.cpp #include <iostream>#include <istream>#include <ostream>#include <string>#include <boost/asio.hpp>using boost::asio::ip::tcp;int main(int argc, char* argv[]) {    try {        if (argc != 3) {            std::cout << "Usage: sync_client <server> <path>\n";            std::cout << "Example:\n";            std::cout << "  sync_client www.boost.org /LICENSE_1_0.txt\n";            return 1;        }        boost::asio::io_service io_service;        // Get a list of endpoints corresponding to the server name.        tcp::resolver resolver(io_service);        tcp::resolver::query query(argv[1], "80");        tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);        tcp::resolver::iterator end;        // Try each endpoint until we successfully establish a connection.        tcp::socket socket(io_service);        boost::system::error_code error = boost::asio::error::host_not_found;        while (error && endpoint_iterator != end) {            socket.close();            socket.connect(*endpoint_iterator++, error);        }        if (error)            throw boost::system::system_error(error);        // Form the request. We specify the "Connection: close" header so that the        // server will close the socket after transmitting the response. This will        // allow us to treat all data up until the EOF as the content.        boost::asio::streambuf request;        std::ostream request_stream(&request);        request_stream << "GET " << argv[2] << " HTTP/1.0\r\n";        request_stream << "Host: " << argv[1] << "\r\n";        request_stream << "Accept: */*\r\n";        request_stream << "Connection: close\r\n\r\n";        // Send the request.        boost::asio::write(socket, request);        // Read the response status line.        boost::asio::streambuf response;        boost::asio::read_until(socket, response, "\r\n");        // Check that response is OK.        std::istream response_stream(&response);        std::string http_version;        response_stream >> http_version;        unsigned int status_code;        response_stream >> status_code;        std::string status_message;        std::getline(response_stream, status_message);        if (!response_stream || http_version.substr(0, 5) != "HTTP/") {            std::cout << "Invalid response\n";            return 1;        }        if (status_code != 200) {            std::cout << "Response returned with status code " << status_code                    << "\n";            return 1;        }        // Read the response headers, which are terminated by a blank line.        boost::asio::read_until(socket, response, "\r\n\r\n");        // Process the response headers.        std::string header;        while (std::getline(response_stream, header) && header != "\r");            std::cout << header << "\n";        std::cout << "\n";        // Write whatever content we already have to output.        if (response.size() > 0)            std::cout << &response;        // Read until EOF, writing data to output as we go.        while (boost::asio::read(socket, response,                boost::asio::transfer_at_least(1), error))            std::cout << &response;        if (error != boost::asio::error::eof)            throw boost::system::system_error(error);    } catch (std::exception& e) {        std::cout << "Exception: " << e.what() << "\n";    }    return 0;}chunli@Linux:~/boost$ g++ client.cpp -lboost_system -pthread -o C && ./C  www.boost.org /LICENSE_1_0.txtBoost Software License - Version 1.0 - August 17th, 2003Permission is hereby granted, free of charge, to any person or organizationobtaining a copy of the software and accompanying documentation covered bythis license (the "Software") to use, reproduce, display, distribute,execute, and transmit the Software, and to prepare derivative works of theSoftware, and to permit third-parties to whom the Software is furnished todo so, all subject to the following:The copyright notices in the Software and this entire statement, includingthe above license grant, this restriction and the following disclaimer,must be included in all copies of the Software, in whole or in part, andall derivative works of the Software, unless such copies or derivativeworks are solely in the form of machine-executable object code generated bya source language processor.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENTSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLEFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHERDEALINGS IN THE SOFTWARE.chunli@Linux:~/boost$



HTTP异步客户端

chunli@Linux:~/boost$ cat client.cpp #include <iostream>#include <istream>#include <ostream>#include <string>#include <boost/asio.hpp>#include <boost/bind.hpp>using boost::asio::ip::tcp;class client {public:    client(boost::asio::io_service& io_service, const std::string& server,            const std::string& path) :        resolver_(io_service), socket_(io_service) {        // Form the request. We specify the "Connection: close" header so that the        // server will close the socket after transmitting the response. This will        // allow us to treat all data up until the EOF as the content.        std::ostream request_stream(&request_);        request_stream << "GET " << path << " HTTP/1.0\r\n";        request_stream << "Host: " << server << "\r\n";        request_stream << "Accept: */*\r\n";        request_stream << "Connection: close\r\n\r\n";        // Start an asynchronous resolve to translate the server and service names        // into a list of endpoints.        tcp::resolver::query query(server, "http");        resolver_.async_resolve(query, boost::bind(&client::handle_resolve,                this, boost::asio::placeholders::error,                boost::asio::placeholders::iterator));    }private:    void handle_resolve(const boost::system::error_code& err,            tcp::resolver::iterator endpoint_iterator) {        if (!err) {            // Attempt a connection to the first endpoint in the list. Each endpoint            // will be tried until we successfully establish a connection.            tcp::endpoint endpoint = *endpoint_iterator;            socket_.async_connect(endpoint, boost::bind(                    &client::handle_connect, this,                    boost::asio::placeholders::error, ++endpoint_iterator));        } else {            std::cout << "Error: " << err.message() << "\n";        }    }    void handle_connect(const boost::system::error_code& err,            tcp::resolver::iterator endpoint_iterator) {        if (!err) {            // The connection was successful. Send the request.            boost::asio::async_write(socket_, request_, boost::bind(                    &client::handle_write_request, this,                    boost::asio::placeholders::error));        } else if (endpoint_iterator != tcp::resolver::iterator()) {            // The connection failed. Try the next endpoint in the list.            socket_.close();            tcp::endpoint endpoint = *endpoint_iterator;            socket_.async_connect(endpoint, boost::bind(                    &client::handle_connect, this,                    boost::asio::placeholders::error, ++endpoint_iterator));        } else {            std::cout << "Error: " << err.message() << "\n";        }    }    void handle_write_request(const boost::system::error_code& err) {        if (!err) {            // Read the response status line.            boost::asio::async_read_until(socket_, response_, "\r\n",                    boost::bind(&client::handle_read_status_line, this,                            boost::asio::placeholders::error));        } else {            std::cout << "Error: " << err.message() << "\n";        }    }    void handle_read_status_line(const boost::system::error_code& err) {        if (!err) {            // Check that response is OK.            std::istream response_stream(&response_);            std::string http_version;            response_stream >> http_version;            unsigned int status_code;            response_stream >> status_code;            std::string status_message;            std::getline(response_stream, status_message);            if (!response_stream || http_version.substr(0, 5) != "HTTP/") {                std::cout << "Invalid response\n";                return;            }            if (status_code != 200) {                std::cout << "Response returned with status code ";                std::cout << status_code << "\n";                return;            }            // Read the response headers, which are terminated by a blank line.            boost::asio::async_read_until(socket_, response_, "\r\n\r\n",                    boost::bind(&client::handle_read_headers, this,                            boost::asio::placeholders::error));        } else {            std::cout << "Error: " << err << "\n";        }    }    void handle_read_headers(const boost::system::error_code& err) {        if (!err) {            // Process the response headers.            std::istream response_stream(&response_);            std::string header;            while (std::getline(response_stream, header) && header != "\r")                std::cout << header << "\n";            std::cout << "\n";            // Write whatever content we already have to output.            if (response_.size() > 0)                std::cout << &response_;            // Start reading remaining data until EOF.            boost::asio::async_read(socket_, response_,                    boost::asio::transfer_at_least(1), boost::bind(                            &client::handle_read_content, this,                            boost::asio::placeholders::error));        } else {            std::cout << "Error: " << err << "\n";        }    }    void handle_read_content(const boost::system::error_code& err) {        if (!err) {            // Write all of the data that has been read so far.            std::cout << &response_;            // Continue reading remaining data until EOF.            boost::asio::async_read(socket_, response_,                    boost::asio::transfer_at_least(1), boost::bind(                            &client::handle_read_content, this,                            boost::asio::placeholders::error));        } else if (err != boost::asio::error::eof) {            std::cout << "Error: " << err << "\n";        }    }    tcp::resolver resolver_;    tcp::socket socket_;    boost::asio::streambuf request_;    boost::asio::streambuf response_;};int main(int argc, char* argv[]) {    try {        if (argc != 3) {            std::cout << "Usage: async_client <server> <path>\n";            std::cout << "Example:\n";            std::cout << "  async_client www.boost.org /LICENSE_1_0.txt\n";            return 1;        }        boost::asio::io_service io_service;        client c(io_service, argv[1], argv[2]);        io_service.run();    } catch (std::exception& e) {        std::cout << "Exception: " << e.what() << "\n";    }    return 0;}chunli@Linux:~/boost$ g++ client.cpp -lboost_system -pthread -o C && ./C  www.boost.org /LICENSE_1_0.txtDate: Wed, 28 Dec 2016 05:06:25 GMTServer: Apache/2.2.15 (Red Hat)Last-Modified: Sun, 15 Dec 2013 02:55:11 GMTETag: "2c53e9-53a-4ed89d2e171f1"Accept-Ranges: bytesContent-Length: 1338Connection: closeContent-Type: text/plainBoost Software License - Version 1.0 - August 17th, 2003Permission is hereby granted, free of charge, to any person or organizationobtaining a copy of the software and accompanying documentation covered bythis license (the "Software") to use, reproduce, display, distribute,execute, and transmit the Software, and to prepare derivative works of theSoftware, and to permit third-parties to whom the Software is furnished todo so, all subject to the following:The copyright notices in the Software and this entire statement, includingthe above license grant, this restriction and the following disclaimer,must be included in all copies of the Software, in whole or in part, andall derivative works of the Software, unless such copies or derivativeworks are solely in the form of machine-executable object code generated bya source language processor.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENTSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLEFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHERDEALINGS IN THE SOFTWARE.chunli@Linux:~/boost$



同步实验:

chunli@Linux:~/boost$ cat main.cpp #include <iostream>#include <boost/asio.hpp>#include <boost/date_time/posix_time/posix_time.hpp>int main() {    boost::asio::io_service io;    boost::asio::deadline_timer t(io,        boost::posix_time::seconds(5));    t.wait();    std::cout << "Hello, world!\n";    return 0;}chunli@Linux:~/boost$ g++ main.cpp -lboost_system && ./a.out Hello, world!chunli@Linux:~/boost$



异步实验

chunli@Linux:~/boost$ cat main.cpp #include <iostream>#include <boost/asio.hpp>#include <boost/date_time/posix_time/posix_time.hpp>void print(const boost::system::error_code& /*e*/) {    std::cout << "Hello, world!\n";}int main() {    boost::asio::io_service io;    boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));    t.async_wait(print);    std::cout << "---------------------" << std::endl;    io.run();    return 0;}chunli@Linux:~/boost$ g++ main.cpp -lboost_system && ./a.out ---------------------Hello, world!chunli@Linux:~/boost$



多线程异步实验

chunli@Linux:~/boost$ cat main.cpp #include <iostream>#include <boost/asio.hpp>#include <boost/thread.hpp>#include <boost/bind.hpp>#include <boost/date_time/posix_time/posix_time.hpp>class printer {public:    printer(boost::asio::io_service& io) :        strand_(io), timer1_(io, boost::posix_time::seconds(1)), timer2_(io,                boost::posix_time::seconds(1)), count_(0) {        timer1_.async_wait(strand_.wrap(boost::bind(&printer::print1, this)));        timer2_.async_wait(strand_.wrap(boost::bind(&printer::print2, this)));    }    ~printer() {        std::cout << "Final count is " << count_ << "\n";    }    void print1() {        if (count_ < 10) {            std::cout << "Timer 1: " << count_ << "\n";            ++count_;            timer1_.expires_at(timer1_.expires_at()                    + boost::posix_time::seconds(1));            timer1_.async_wait(                    strand_.wrap(boost::bind(&printer::print1, this)));        }    }    void print2() {        if (count_ < 10) {            std::cout << "Timer 2: " << count_ << "\n";            ++count_;            timer2_.expires_at(timer2_.expires_at()                    + boost::posix_time::seconds(1));            timer2_.async_wait(                    strand_.wrap(boost::bind(&printer::print2, this)));        }    }private:    boost::asio::strand strand_;    boost::asio::deadline_timer timer1_;    boost::asio::deadline_timer timer2_;    int count_;};int main() {    boost::asio::io_service io;    printer p(io);    boost::thread t(boost::bind(&boost::asio::io_service::run, &io));    io.run();    t.join();    return 0;}chunli@Linux:~/boost$ g++ main.cpp -lboost_system -lboost_thread && ./a.out Timer 1: 0Timer 2: 1Timer 1: 2Timer 2: 3Timer 1: 4Timer 2: 5Timer 1: 6Timer 2: 7Timer 1: 8Timer 2: 9Final count is 10chunli@Linux:~/boost$



本文出自 “李春利” 博客,请务必保留此出处http://990487026.blog.51cto.com/10133282/1886852