使用boost::asio开发网络服务器
来源:互联网 发布:地外文明知乎 编辑:程序博客网 时间:2024/05/02 00:57
作为简单的示例,说明, 此服务器只是作为简单的数据收发示例,没有加入reactor模式的事件分法机制如select/epoll, 有待进一步完善。
因代码并非完全独自编写,所以注明是转载。
服务器端
#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>#include <iostream>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("127.0.0.1"/*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;}
0 0
- 使用boost::asio开发网络服务器
- Boost Asio服务器使用
- [Boost.asio] 深入linux网络编程(四):使用asio搭建商用服务器
- BOOST网络库-ASIO
- boost asio网络编程
- boost:asio网络库初学之echo服务器客户端实现
- C++ 建立本地网络服务器 (Boost.Asio库)
- 基于Boost.Asio的异步通信服务器设计与开发
- [转]自己开发的基于boost::asio的网络引擎
- 自己开发的基于boost asio的网络引擎
- [转]自己开发的基于boost::asio的网络引擎
- boost.asio 使用点滴
- boost::asio 使用实例
- boost asio使用注意事项
- Boost.Asio使用实例
- boost.asio服务器使用io_service作为work pool
- boost.asio服务器使用io_service作为work pool
- boost.asio服务器使用io_service作为work pool
- 2016--超越
- 非常适合用于查看linux内核代码的网站
- CreateFile,ReadFile等API详解(或者说MSDN的翻译)
- C#基础入门典型例题(3)
- 【NYOJ】[100]1的个数
- 使用boost::asio开发网络服务器
- 【学习笔记】 UFLDL-1
- Linux下NTP服务器及客户端配置
- Uva10881 Piotr's Ants
- 使用unity做的绩点计算器
- ngnix下conf通用设置方法(php fastcgi)
- CodeForces 620E New Year Tree(线段树)
- centos 7安装ifconfig
- cf#11-B - Jumping Jack-数学