我尝试使用TCP-Server,它正在读取数据,处理它们并将它们发回。之后它将等待新的数据。我的问题是,服务器第一次发送数据时工作正常。第二次,程序保持在run_one()
- 循环。
size_t m_lengthReceive;
io_service m_ioService;
std::vector<unsigned char> m_vectorBuffer;
unsigned char m_bufferReceive[128];
void SyncServer::initialize(){
m_acceptor = shared_ptr<tcp::acceptor>(
new tcp::acceptor(m_ioService,
tcp::endpoint(tcp::v4(), m_port)));
m_acceptor->set_option(tcp::acceptor::reuse_address(true));
m_sock = shared_ptr<tcp::socket>(new tcp::socket(m_ioService));
m_acceptor->accept(*m_sock, m_ec);
}
void SyncServer::tcpReceiveVector(){
boost::system::error_code ec;
m_sock->async_read_some(buffer(m_bufferReceive),
boost::bind(&SyncServer::tcpReceiveHandler, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
do{
m_ioService.run_one();
}while(m_lengthReceive == 0);
}
void SyncServer::tcpReceiveHandler(const boost::system::error_code& ec,
size_t size){
if(size > 0 && !ec){
m_sock->cancel();
m_lengthReceive = size;
m_vectorBuffer.resize(m_lengthReceive);
int i = 0;
for(std::vector<unsigned char>::iterator it = m_vectorBuffer.begin();
it != m_vectorBuffer.end(); ++it){
*it = m_bufferReceive[i];
++i;
}
}else{
m_lengthReceive = 0;
m_sock->async_read_some(buffer(m_bufferReceive),
boost::bind(&SyncServer::tcpReceiveHandler, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
std::vector<unsigned char> SyncServer::getVectorBuffer(){
return m_vectorBuffer;
}
void SyncServer::openConnection(){
if(!m_sock->is_open())
m_sock->open(tcp::v4());
m_lengthReceive = 0;
}
void SyncServer::closeConnection(){
m_sock->close();
}
main(){
m_tcpServer = shared_ptr<SyncServer>(new SyncServer(m_tcpPort));
m_tcpServer->initialize();
while(1){
m_tcpServer->openConnection();
m_tcpServer->tcpReceiveVector();
vector = m_tcpServer->getVectorBuffer();
//do something with vector
m_tcpServer->tcpSend(vector); //this works fine
m_tcpServer->closeConnection();
}
}
更新代码:
void SyncServer::tcpReceiveHandler(const boost::system::error_code& ec,
size_t size){
if(ec){
std::cout<< ec << std::endl;
}else{
if(size > 0){
m_sock->cancel();
m_lengthReceive = size;
m_vectorBuffer.resize(m_lengthReceive);
int i = 0;
for(std::vector<unsigned char>::iterator it = m_vectorBuffer.begin();
it != m_vectorBuffer.end(); ++it){
*it = m_bufferReceive[i];
++i;
}
}else{
m_lengthReceive = 0;
m_sock->async_read_some(buffer(m_bufferReceive),
boost::bind(&SyncServer::tcpReceiveHandler, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
}
答案 0 :(得分:2)
在接收处理程序中,如果出现问题(?)
,则只会触发另一次读取void SyncServer::tcpReceiveHandler(const boost::system::error_code& ec,
size_t size){
if(size > 0 && !ec){
m_sock->cancel();
m_lengthReceive = size;
m_vectorBuffer.resize(m_lengthReceive);
int i = 0;
for(std::vector<unsigned char>::iterator it = m_vectorBuffer.begin();
it != m_vectorBuffer.end(); ++it){
*it = m_bufferReceive[i];
++i;
}
}else{
m_lengthReceive = 0;
m_sock->async_read_some(buffer(m_bufferReceive),
boost::bind(&SyncServer::tcpReceiveHandler, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
在这个回调中,你需要排队下一次读取(通常是在没有问题的情况下,而不是在出现问题时!)
答案 1 :(得分:1)
除了Nim回答之外,你还做了经典的asio错误。如此处所述:http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/io_service/run_one/overload1.html “对run(),run_one(),poll()或poll_one()的后续调用将立即返回,除非事先调用reset()。”
在您.run_one
之后,您需要致电m_ioservice.reset()
,否则它将再也无法运行。它只是返回而不是调用任何任何异步操作,因此m_lengthReceive
在第一次之后不会改变。
do{
m_ioService.run_one();
m_ioService.reset();
}while(m_lengthReceive == 0);
这是人们通常不使用run_one()
而是使用run()
并在最后一个处理程序中启动新的异步操作的原因。在这种情况下,run()
不会返回,也不需要reset()
。