boost::async_read_some连续接收数据

From: http://blog.sina.com.cn/s/blog_5cf4a61d01010jnw.html

我在最近工作的时候用到了boost的http_server程序,这个http_server是一个框架用于接收并解析http协议。这个框架在接收get请求时没有任何问题,当接收post数据时,当数据大于>2k时,无法正确接收,后来发现sync_read_some函数一次只能接收大约1k数据,如果要接收大数据,需要反复接收,自己修改了几天,将经验分享一下。

/*
	参考: http://blog.sina.com.cn/s/blog_5cf4a61d01010jnw.html
	因为网上的代码不全,我试着补了部分代码,应该还不全,所以无法完全通过编译!凑合着看看吧!

	Fedora20下编译: g++ -o aa aa.cpp -Os -std=c++11 -lboost_system
*/

#include <iostream>
#include <boost/array.hpp>
#include <boost/timer.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

using namespace std;
using boost::asio::ip::tcp;

//接收数据的buffer
boost::array<char, 8192> buffer_;
//数据需要多次接收,将多次接收的数据都放入data中
std::string data;

class connection
{
public:
	void start();
	void close_connect1();
	void handle_read1(const boost::system::error_code& e, std::size_t bytes_transferred, string& data);
	void handle_write();

private:
	tcp::socket				socket_;
	boost::timer			timer;
	boost::request_handler	request_handler_;
};

void connection::start()
{
	//超时限制
	timer.expires_from_now(boost::posix_time::microseconds(1000000));
	timer.async_wait(boost::bind(&connection::close_connect1, this));

	buffer_.data()[0] = '\0';
	//开始接收数据
	socket_.async_read_some(boost::asio::buffer(buffer_),
			boost::bind(&connection::handle_read1, shared_from_this(),
				boost::asio::placeholders::error,
				boost::asio::placeholders::bytes_transferred,data));
	return;
}

void connection::close_connect1()
{
	// TODO:
}

void connection::handle_read1(const boost::system::error_code& e, std::size_t bytes_transferred, string& data)
{
	//如果超时,返回空
	if(!m_flag)
	{
		m_flag = true;
		request_handler_.handle_request1(request_, reply_);
		boost::asio::async_write(socket_, reply_.to_buffers(),
								boost::bind(&connection::handle_write, shared_from_this(),
								boost::asio::placeholders::error));

		boost::system::error_code ignored_ec;
		socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
		return;
	}
	//如果接收有错误或者接收的数据长度=0,和超时处理一致
	if(e || bytes_transferred==0)
	{
		request_handler_.handle_request1(request_, reply_);
		boost::asio::async_write(socket_, reply_.to_buffers(),
				boost::bind(&connection::handle_write, shared_from_this(),
					boost::asio::placeholders::error));
		boost::system::error_code ignored_ec;
		socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
		return;
	}
	else
	{
		buffer_.data()[bytes_transferred] = '\0';
		data = data + buffer_.data();
		//表示接收到了结束标志
		if (data.find("|*|*|") != string::npos)
		{
			int pos = data.find("|*|*|");
			printf("pos=%d\n",pos);
			data = data.substr(0,pos);

			if(data.length()>0)
			{
				//时钟取消
				timer.cancel();
				//用于处理接收的数据并将处理完的数据返回去,处理完的数据存储在reply中
				request_handler_.handle_request_pos(request_, reply_,data);
				boost::asio::async_write(socket_, reply_.to_buffers(),
						boost::bind(&connection::handle_write, shared_from_this(),
							boost::asio::placeholders::error));
			}
			else
			{
				request_handler_.handle_request1(request_, reply_);
				boost::asio::async_write(socket_, reply_.to_buffers(),
						boost::bind(&connection::handle_write, shared_from_this(),
							boost::asio::placeholders::error));
			}
			boost::system::error_code ignored_ec;
			socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignored_ec);
			return;

		}
		//如果上面的if条件不满足,表示还在等待接收数据
		socket_.async_read_some(boost::asio::buffer(buffer_),
				boost::bind(&connection::handle_read1, shared_from_this(),
					boost::asio::placeholders::error,
					boost::asio::placeholders::bytes_transferred,
					data));
	}
}

void connection::handle_write()
{
	// TODO:
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值