码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2016-12-28 21:42:41      阅读:798      评论:0      收藏:0      [点我收藏+]

标签:10 c++ boost asio网路通信库 tcp/udp   http   

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

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

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

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

HTTP同步客户端
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 -tnlp
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        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 8080
Tue Dec 27 13:06:53 2016
chunli@Linux:~$ nc 127.0.0.1 8080
Tue Dec 27 13:06:55 2016
chunli@Linux:~$ nc 127.0.0.1 8080
Tue Dec 27 13:06:55 2016
chunli@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; // #1
		tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 8868)); // #2
		while(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]: 1
Tue Dec 27 13:41:51 2016
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]: 2
 13:41:54 up  3:39,  4 users,  load average: 0.07, 0.03, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
chunli   pts/6    chunli-pc        10:03    1:22   3.69s  3.37s vim main.cpp
chunli   pts/10   chunli-pc        11:58    1:14   0.89s  0.00s sh -c w > who
chunli   :0       :0               12:41   ?xdm?   4:25   0.44s init --user
chunli   pts/0    chunli-pc        13:06    2.00s  0.33s  0.00s nc 127.0.0.1 8868
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]: 3
Linux 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/Linux
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]: 4
Sorry, no such service.
chunli@Linux:~/boost$


技术分享



多线程的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 client
	boost::system::error_code ignored_error;
	boost::asio::write(*socket, boost::asio::buffer(serviceList),
			boost::asio::transfer_all(), ignored_error);

	// 2, receive selection from client
	char selection[20];
	size_t n = socket->read_some(boost::asio::buffer(selection), ignored_error);
	// 3, send response
	string 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; // #1
		tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 8868)); // #2
		boost::thread_group grp;
		for (;;) {
			SocketPtr socket(new tcp::socket(io_service)); // #3
			acceptor.accept(*socket); // #4
			grp.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_service
		tcp::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 server
		len = 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 && ./client
www.baidu.com 443
115.239.210.27:443
115.239.211.112:443

www.taobao.com 80
101.227.208.227:80
101.227.208.226:80
114.80.174.46:80
222.73.134.63:80
114.80.174.47:80

51cto.com 80
123.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.out

chunli@Linux:~/boost$ nc 127.0.0.1 8080
hello
hello
hello World
hello 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 message
				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));
			}
		}
		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(&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 && ./client
hello
hello
haha
haha



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 && ./S

chunli@Linux:~$ netstat -unlp
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
udp        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 8868
hello
hello
中国上海!
中国上海!




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; // #1

		udp::resolver resolver(service); // #2
		udp::resolver::query query(udp::v4(), "localhost", "8868"); // #3
		udp::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());// #5
		char buf[512];
		for (;;) {
			memset(buf, 0, 512);
			cin.getline(buf, 512);
			socket.send_to(boost::asio::buffer(buf, strlen(buf)),
					receiverEndpoint); // #6
			memset(buf, 0, 512);
			udp::endpoint senderEndpoint; // #7
			socket.receive_from(boost::asio::buffer(buf), senderEndpoint); // #8
			cout << 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 && ./S
127.0.0.1:36398
127.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 && ./C
127.0.0.1:8868
haha
haha
中国上海
中国上海



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.txt


Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:

The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR 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 OTHER
DEALINGS 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.txt
Date: Wed, 28 Dec 2016 05:06:25 GMT
Server: Apache/2.2.15 (Red Hat)
Last-Modified: Sun, 15 Dec 2013 02:55:11 GMT
ETag: "2c53e9-53a-4ed89d2e171f1"
Accept-Ranges: bytes
Content-Length: 1338
Connection: close
Content-Type: text/plain

Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:

The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR 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 OTHER
DEALINGS 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: 0
Timer 2: 1
Timer 1: 2
Timer 2: 3
Timer 1: 4
Timer 2: 5
Timer 1: 6
Timer 2: 7
Timer 1: 8
Timer 2: 9
Final count is 10
chunli@Linux:~/boost$



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

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

标签:10 c++ boost asio网路通信库 tcp/udp   http   

原文地址:http://990487026.blog.51cto.com/10133282/1886852

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!