我想写基于IO_Service的异步TCP客户端,其中Async_write工作正常,但async_read在无限循环中运行。在我尝试纠正这个问题的过程中,我发现在所有其他情况下,async_read只是停止接收数据,直到我停止服务器时才会收到任何内容。以下是发布我的查询之前我尝试的代码和链接。boost :: asio :: async_read循环无限与零字节的接收数据
我试过的建议是exactly as mine,2,3and但在所有的情况下,我async_read处理程序不读什么。在一个也是唯一的情况下,它开始无限循环,当我设置缓冲区为boost::asio::mutable_buffer bytes;
在其他情况下,我已经尝试boost::array<char, 512> bytes;
,boost::asio::streambuf bytes;
和char bytes[512];
其中未引发async_read处理程序。
经历了所有这些解决方案后,我现在感到困惑:它可能是缓冲区的问题吗?在通过阅读 之前,我需要初始化吗?
请指导。
ScalableSocket::ScalableSocket()
{
//ctor
using namespace boost::asio;
service = boost::make_shared<io_service>();
work = boost::make_shared<io_service::work>(*service);
strand = boost::make_shared<io_service::strand>(*service);
worker_threads = boost::make_shared<boost::thread_group>();
worker_threads->create_thread(boost::bind(&ScalableSocket::WorkerThread,this));
resolver = boost::make_shared<boost::asio::ip::tcp::resolver> (*service);
tcp_socket= boost::make_shared<boost::asio::ip::tcp::socket> (*service);
boost::asio::ip::tcp::resolver::query q(boost::asio::ip::tcp::v4(),"192.168.100.96","9602");
boost::asio::ip::tcp::resolver::iterator it = resolver->resolve(q);
boost::asio::async_connect(*tcp_socket,it,boost::bind(&ScalableSocket::connect_handler,this,boost::asio::placeholders::error));
tcp_socket->set_option(boost::asio::ip::tcp::no_delay(true));
}
ScalableSocket::~ScalableSocket()
{
//dtor
}
void ScalableSocket::PublishPost()
{
strand->post(boost::bind(&ScalableSocket::OnSend,this));
}
void ScalableSocket::OnSend()
{
boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' };
boost::asio::async_write(*tcp_socket,boost::asio::buffer(a),
boost::bind(&ScalableSocket::write_handler, this, boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
}
void ScalableSocket::WorkerThread()
{
while(true)
{
try
{
boost::system::error_code ec;
service->run(ec);
if(ec)
{
///LOGE(ec);
}
break;
}
catch(std::exception & ex)
{
///LOGE(ex.what());
}
}
}
void ScalableSocket::connect_handler(const boost::system::error_code &ec)
{
if (!ec)
{
PublishPost();
/* boost::asio::async_read(*tcp_socket,
boost::asio::buffer(bytes),
boost::bind(&ScalableSocket::read_handler, this,
boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
*/
///https://stackoverflow.com/questions/4527443/problems-using-boostasioasync-read
boost::shared_ptr<boost::array<char, 512>> buf(new boost::array<char, 512>);
boost::asio::async_read(*tcp_socket,boost::asio::buffer(*buf),
boost::bind(&ScalableSocket::read_handler, this,buf,
boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
}
else
{
cout<<" Some error connecting to Exchange "<< ec.message()<<endl;
}
}
void ScalableSocket::OnTimer(const boost::system::error_code &ec)
{
if(!ec)
{
printf("\n\n Heartbeat event raised sending KeepAlive to exchange \n\n");
PublishPost();
HeartBeatTimer->async_wait(boost::bind(&ScalableSocket::OnTimer,this, boost::asio::placeholders::error));
}
}
void ScalableSocket::recvData()
{
boost::system::error_code error;
boost::array<char, 1024> buf;
//for(;;)
{
size_t len = tcp_socket->read_some(boost::asio::buffer(buf), error);
cout<<"\n Recv data size is "<<len;
}
}
void ScalableSocket::read_handler(boost::shared_ptr<boost::array<char, 512>> buf,const boost::system::error_code &ec,std::size_t bytes_transferred)
{
if (!ec)//&& bytes_transferred > 0)
{
///recvData(); /// If i enable this code during infinite loop it start getting data that means socket has no issue
cout << " Data size recieved "<< bytes_transferred<<endl;
boost::asio::async_read(*tcp_socket,boost::asio::buffer(*buf),
boost::bind(&ScalableSocket::read_handler, this,buf,
boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
}
else
{
/// Some issue with socket publish error , inform user and reconnect
cout<<" Some error reading data from Exchange "<< ec.message()<<endl;
}
}
void ScalableSocket::write_handler(const boost::system::error_code& error,std::size_t bytes_transferred)
{
if(!error)
{
/// data Sent successfully
cout<< " Data sent size "<< bytes_transferred<<endl;
}
else
{
cout<<" Some error sending data to Exchange "<< error.message()<<endl;
}
}
但你知道'asnyc_read'将不会“返回”/调用处理程序,直到给定的缓冲区完全满了,对吗? – Blacktempel
我使用这种512种缓冲,一旦我没有收到任何东西使用boost streambuffer或可变缓冲区,然后我尝试使用512的东西,遵循堆栈本身的一些解决方案 –
一些标点符号将有助于识别您的评论。尝试发送512字节以上的数据,看看您是否收到了正确的数据。 – Blacktempel