asio异步网络通信实例

服务端:

#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 1024

class 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]*/;
	//我们用的是inet4

	tcp::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实例化了
	{
		//连接服务端 connect
		socket.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是一个基本性的接口,基本上通常用到的类实例都需要通过它来构造
	//功能我们可以看似socket
	boost::asio::io_service io_service;
	//这个终端就是服务器
	//它的定义就可以看作时sockaddr_in,我们用它来定义IP和PORT
	tcp::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;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值