Boost asio之网络编程

来源:互联网 发布:pe软件下载 编辑:程序博客网 时间:2024/05/22 12:25

 最近要用到boost的asio库做个网络编程的程序,不知道从何下手,就开始在网上找资料,首先先把boost库下载了下来,下载地址是:www.boost.org,然后开始找书,发现这方面的书实在是太少了,当当网上只有一本《Boost程序库完全开发指南》电子版里只笔带过,还好找了个网址,上面有汉化的文档,先啃啃吧http://code.google.com/p/boost-doc-zh/,希望有用,以下的内容是从网上找的例子,先贴上来,对于我这样的菜鸟,路漫漫其修远兮。

boost库中的网络编程的例子比较复杂,不太好理解,所以,从网上找了一个简单点的例子。网址如下:http://blog.chinaunix.net/u3/93184/showart_1846119.html.经过修改,可以运行。

服务器代码:

Servier.cpp#include <boost/asio.hpp>#include <boost/bind.hpp>#include <boost/shared_ptr.hpp>#include <boost/enable_shared_from_this.hpp>#include <iostream>using boost::asio::ip::tcp;#define max_len 1024class clientSession:public boost::enable_shared_from_this<clientSession>{public:clientSession(boost::asio::io_service& ioservice):m_socket(ioservice){memset(data_,‘\0′,sizeof(data_));}~clientSession(){}tcp::socket& socket(){return m_socket;}void start(){boost::asio::async_write(m_socket,boost::asio::buffer(“link successed!”),boost::bind(&clientSession::handle_write,shared_from_this(),boost::asio::placeholders::error));/*async_read跟客户端一样,还是不能进入handle_read函数,如果你能找到问题所在,请告诉我,谢谢*/// --已经解决,boost::asio::async_read(...)读取的字节长度不能大于数据流的长度,否则就会进入// ioservice.run()线程等待,read后面的就不执行了。//boost::asio::async_read(m_socket,boost::asio::buffer(data_,max_len),//         boost::bind(&clientSession::handle_read,shared_from_this(),//         boost::asio::placeholders::error));//max_len可以换成较小的数字,就会发现async_read_some可以连续接收未收完的数据m_socket.async_read_some(boost::asio::buffer(data_,max_len),boost::bind(&clientSession::handle_read,shared_from_this(),boost::asio::placeholders::error));}private:void handle_write(const boost::system::error_code& error){if(error){m_socket.close();}}void handle_read(const boost::system::error_code& error){if(!error){std::cout << data_ << std::endl;//boost::asio::async_read(m_socket,boost::asio::buffer(data_,max_len),//     boost::bind(&clientSession::handle_read,shared_from_this(),//     boost::asio::placeholders::error));m_socket.async_read_some(boost::asio::buffer(data_,max_len),boost::bind(&clientSession::handle_read,shared_from_this(),boost::asio::placeholders::error));}else{m_socket.close();}}private:tcp::socket m_socket;char data_[max_len];};class serverApp{typedef boost::shared_ptr<clientSession> session_ptr;public:serverApp(boost::asio::io_service& ioservice,tcp::endpoint& endpoint):m_ioservice(ioservice),acceptor_(ioservice,endpoint){session_ptr new_session(new clientSession(ioservice));acceptor_.async_accept(new_session->socket(),boost::bind(&serverApp::handle_accept,this,boost::asio::placeholders::error,new_session));}~serverApp(){}private:void handle_accept(const boost::system::error_code& error,session_ptr& session){if(!error){std::cout << “get a new client!” << std::endl;//实现对每个客户端的数据处理session->start();//在这就应该看出为什么要封session类了吧,每一个session就是一个客户端session_ptr new_session(new clientSession(m_ioservice));acceptor_.async_accept(new_session->socket(),boost::bind(&serverApp::handle_accept,this,boost::asio::placeholders::error,new_session));}}private:boost::asio::io_service& m_ioservice;tcp::acceptor acceptor_;};int main(int argc , char* argv[]){boost::asio::io_service myIoService;short port = 8100/*argv[1]*/;//我们用的是inet4tcp::endpoint endPoint(tcp::v4(),port);//终端(可以看作sockaddr_in)完成后,就要accept了serverApp sa(myIoService,endPoint);//数据收发逻辑myIoService.run();return 0;}


 

客户端代码:

#include <boost/asio.hpp>#include <boost/bind.hpp>#include <boost/shared_ptr.hpp>using boost::asio::ip::tcp;class client{public:client(boost::asio::io_service& io_service,tcp::endpoint& endpoint): socket(io_service)//这里就把socket实例化了{//连接服务端 connectsocket.async_connect(endpoint,boost::bind(&client::handle_connect,this,boost::asio::placeholders::error));memset(getBuffer,‘\0′,1024);}~client(){}private:void handle_connect(const boost::system::error_code& error){if(!error){//一连上,就向服务端发送信息boost::asio::async_write(socket,boost::asio::buffer(“hello,server!”),boost::bind(&client::handle_write,this,boost::asio::placeholders::error));/**读取服务端发下来的信息*这里很奇怪,用async_read根本就不能进入handle_read函数**/// --已经解决,boost::asio::async_read(...)读取的字节长度不能大于数据流的长度,否则就会进入// ioservice.run()线程等待,read后面的就不执行了。//boost::asio::async_read(socket,//     boost::asio::buffer(getBuffer,1024),//     boost::bind(&client::handle_read,this,boost::asio::placeholders::error)//    );socket.async_read_some(boost::asio::buffer(getBuffer,1024),boost::bind(&client::handle_read,this,boost::asio::placeholders::error));}else{socket.close();}}void handle_read(const boost::system::error_code& error){if(!error){std::cout << getBuffer << std::endl;//boost::asio::async_read(socket,//         boost::asio::buffer(getBuffer,1024),//         boost::bind(&client::handle_read,this,boost::asio::placeholders::error)//        );//这样就可以实现循环读取了,相当于while(1)//当然,到了这里,做过网络的朋友就应该相当熟悉了,一些逻辑就可以自行扩展了//想做聊天室的朋友可以用多线程来实现socket.async_read_some(boost::asio::buffer(getBuffer,1024),boost::bind(&client::handle_read,this,boost::asio::placeholders::error));}else{socket.close();}}void handle_write(const boost::system::error_code& error){}private:tcp::socket socket;char getBuffer[1024];};int main(int argc,char* argv[]){//if(argc != 3)//{// std::cerr << “Usage: chat_client <host> <port>\n”;//    return 1;//}//我觉IO_SERVICE是一个基本性的接口,基本上通常用到的类实例都需要通过它来构造//功能我们可以看似socketboost::asio::io_service io_service;//这个终端就是服务器//它的定义就可以看作时sockaddr_in,我们用它来定义IP和PORTtcp::endpoint endpoint(boost::asio::ip::address_v4::from_string("192.168.1.119"/*argv[1]*/),8100/*argv[2]*/);//既然socket和sockaddr_in已经定义好了,那么,就可以CONNECT了//之所以为了要把连接和数据处理封成一个类,就是为了方便管理数据,这点在服务端就会有明显的感觉了boost::shared_ptr<client> client_ptr(new client(io_service,endpoint));//执行收发数据的函数io_service.run();return 0;}

修改192.168.1.119为127.0.0.1,然后先运行server,再运行client,一切ok.



 

原创粉丝点击