C++ 正确终止boost::asio::ip::tcp::accept(Linux)
我想知道如何使用boost实现一个可以终止的同步套接字accept 为了证明我的问题,我稍微修改了 注意:提供的代码似乎在Windows平台上运行,但我在Linux机器上遇到问题 假设服务器收到一条退出消息,现在想要终止一个接受新连接的无止境循环。 大多数教程等都建议您在这种情况下运行acceptor->close()。但作为 状态,如果从另一个线程调用C++ 正确终止boost::asio::ip::tcp::accept(Linux),c++,boost,synchronous,C++,Boost,Synchronous,我想知道如何使用boost实现一个可以终止的同步套接字accept 为了证明我的问题,我稍微修改了 注意:提供的代码似乎在Windows平台上运行,但我在Linux机器上遇到问题 假设服务器收到一条退出消息,现在想要终止一个接受新连接的无止境循环。 大多数教程等都建议您在这种情况下运行acceptor->close()。但作为 状态,如果从另一个线程调用close(),则结果可能未定义 如果您这样做,accept()这次不会终止,但当另一个客户端尝试连接时,它会返回一个错误(在Linux上!)
close()
,则结果可能未定义
如果您这样做,accept()
这次不会终止,但当另一个客户端尝试连接时,它会返回一个错误(在Linux上!)
因此,我的问题是:如何正确地终止一个基于持续同步接受连接的boost::asio
的服务器
代码如下:
#include <cstdlib>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
using boost::asio::ip::tcp;
void session(boost::shared_ptr<tcp::socket> sock, tcp::acceptor *acceptor )
{
try {
for (;;) {
char data[ 1024 ];
boost::system::error_code error;
size_t length = sock->read_some(boost::asio::buffer(data), error);
if (error == boost::asio::error::eof) { break; }
else if (error) { throw boost::system::system_error(error); }
if( std::string("quit") == data ) { // TRY TO CANCEL THE ACCEPT
acceptor->close();
break;
}
boost::asio::write(*sock, boost::asio::buffer(data, length));
}
}
catch (std::exception& e) { std::cerr << "exception in thread: " << e.what() << "\n"; }
}
void server(boost::asio::io_service& io_service, short port)
{
tcp::acceptor a( io_service, tcp::endpoint(tcp::v4(), port) );
for (;;) {
boost::shared_ptr<tcp::socket> sock(new tcp::socket(io_service));
boost::system::error_code error;
a.accept( *sock, error );
if( !error ) {
boost::thread t( boost::bind( session, sock, &a ) );
}
else {
std::cout << "acceptor canceled "<< error << std::endl;
break;
}
}
}
int main(int argc, char* argv[])
{
try{
// ..check args here...
boost::asio::io_service io_service;
server(io_service, std::atoi(argv[1]));
}
catch (std::exception& e) {std::cerr << "Exception: " << e.what() << "\n";}
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
使用boost::asio::ip::tcp;
无效会话(boost::shared_ptr sock,tcp::acceptor*acceptor)
{
试一试{
对于(;;){
字符数据[1024];
boost::system::error\u code error;
size\u t length=sock->read\u some(boost::asio::buffer(data),错误);
if(error==boost::asio::error::eof){break;}
else if(error){throw boost::system::system_error(error);}
如果(std::string(“quit”)==data){//请尝试取消接受
接受者->关闭();
打破
}
boost::asio::write(*sock,boost::asio::buffer(数据,长度));
}
}
catch(std::exception&e){std::cerr我不知道从boost::asio
中取消同步accept
的方法。你能将其重构为使用async_accept()
吗?(答案当然是肯定的——但如果你的实际代码不是像本例中那样微不足道的话,这可能是一些工作)。是的。你为什么要进行阻塞套接字调用?要体验线程应用程序的恐怖,以增加尝试取消同步操作的乐趣?当然要使用非阻塞套接字。如果你坚持,你需要在accept()调用上设置计时器(例如sigallarm)并在每个循环中检查一个标志。50ms警报意味着主线程在处理取消之前不必等待超过50ms。