下面是boost官方给出的ssl服务端例子:
首先,声明了一个流类型的socekt 用来作为socket对象:
1: typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket;
接下来是session类:
1: class session
2: {3: public:
4: session(boost::asio::io_service& io_service,5: boost::asio::ssl::context& context)6: : socket_(io_service, context)7: {8: }9:10: ssl_socket::lowest_layer_type& socket()11: {12: return socket_.lowest_layer();
13: }14:15: void start()
16: {17: socket_.async_handshake(boost::asio::ssl::stream_base::server,18: boost::bind(&session::handle_handshake, this,
19: boost::asio::placeholders::error));20: }21:22: void handle_handshake(const boost::system::error_code& error)23: {24: if (!error)
25: {26: socket_.async_read_some(boost::asio::buffer(data_, max_length),27: boost::bind(&session::handle_read, this,
28: boost::asio::placeholders::error,29: boost::asio::placeholders::bytes_transferred));30: }31: else
32: {33: delete this;34: }35: }36:37: void handle_read(const boost::system::error_code& error,38: size_t bytes_transferred)39: {40: if (!error)
41: {42: boost::asio::async_write(socket_,43: boost::asio::buffer(data_, bytes_transferred),44: boost::bind(&session::handle_write, this,
45: boost::asio::placeholders::error));46: }47: else
48: {49: delete this;50: }51: }52:53: void handle_write(const boost::system::error_code& error)54: {55: if (!error)
56: {57: socket_.async_read_some(boost::asio::buffer(data_, max_length),58: boost::bind(&session::handle_read, this,
59: boost::asio::placeholders::error,60: boost::asio::placeholders::bytes_transferred));61: }62: else
63: {64: delete this;65: }66: }67:68: private:
69: ssl_socket socket_;70: enum { max_length = 1024 };
71: char data_[max_length];
72: };
session类 ,主要的功能就是通信,做一些数据处理的操作。session类声明了3个私有的变量,一个socket,一个枚举的长度值max_length,一个data_作为缓冲区。
session类,提供了2个成员函数,3个回调函数,2个成员函数,第一个socket()的功能是获取一个底层的ssl_socket,第二个start函数的作用是进行通信。
在start()函数中,使用ssl_socket 进行handshake操作,进行数据交互,其回调函数hand_handshake回调成功,则执行读操作,后续是一样的过程;
session类最重要的还是数据的操作,ssl_socket提供了socket加密,此处可忽略数据的加密。
下面是server类:
1: class server
2: {3: public:
4: server(boost::asio::io_service& io_service, unsigned short port)5: : io_service_(io_service),6: acceptor_(io_service,7: boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),8: context_(boost::asio::ssl::context::sslv23)9: {10: context_.set_options( //设置了context的选项
11: boost::asio::ssl::context::default_workarounds12: | boost::asio::ssl::context::no_sslv213: | boost::asio::ssl::context::single_dh_use);14: context_.set_password_callback(boost::bind(&server::get_password, this)); //设置回调函数,获取密码15: context_.use_certificate_chain_file("server.pem");
16: context_.use_private_key_file("server.pem", boost::asio::ssl::context::pem);
17: context_.use_tmp_dh_file("dh512.pem");
18:19: start_accept();20: }21:22: std::string get_password() const //context的回调函数,用于获取密码23: {24: return "test";25: }26:27: void start_accept() //start_accept 执行连接客户端操作28: {29: session* new_session = new session(io_service_, context_);
30: acceptor_.async_accept(new_session->socket(),31: boost::bind(&server::handle_accept, this, new_session,
32: boost::asio::placeholders::error));33: }34:35: void handle_accept(session* new_session, //执行回调函数36: const boost::system::error_code& error)
37: {38: if (!error)
39: {40: new_session->start();41: }42: else
43: {44: delete new_session;
45: }46:47: start_accept();48: }49:50: private:
51: boost::asio::io_service& io_service_;52: boost::asio::ip::tcp::acceptor acceptor_;53: boost::asio::ssl::context context_;54: };
总结:
总的来说,通过ssl的服务端程序,和没有使用ssl的服务端程序的流程是一样的,都是 获取客户端连接->连接成功->执行session通信。
那么,不一样的地方,就是在server类中,需要根据需求设置context 的选项实现加密;boost官方给的例子很简单,实现了一个小小的加密socket的服务端程序,
剩下的功能就需要我们根据自己的需求实现拓展。
东西很简单,如果你有疑问,欢迎评论。。。。有则改之无则加勉!!!