c – 当服务器执行asio :: write操作时客户端断开连接时,Boost T
发布时间:2020-12-16 07:13:15 所属栏目:百科 来源:网络整理
导读:只是为了测试我的服务器,我已经从我的客户端使用for循环创建了100个请求,而我的服务器正在为第N个请求写响应,我故意从客户端按下控制c,就是这样.服务器停止并且没有响应,虽然我尝试使用新连接连接它,任何人都可以建议我如何使我的服务器稳定并免受这种中断.
只是为了测试我的服务器,我已经从我的客户端使用for循环创建了100个请求,而我的服务器正在为第N个请求写响应,我故意从客户端按下控制c,就是这样.服务器停止并且没有响应,虽然我尝试使用新连接连接它,任何人都可以建议我如何使我的服务器稳定并免受这种中断.
这是我的服务器: class tcp_server { public: tcp_server(boost::asio::io_service& io_service) : acceptor_(io_service,tcp::endpoint(tcp::v4(),2020)) { start_accept(); } private: void start_accept() { tcp_connection::pointer new_connection = tcp_connection::create(acceptor_.get_io_service()); acceptor_.async_accept(new_connection->socket(),boost::bind(&tcp_server::handle_accept,this,new_connection,boost::asio::placeholders::error)); } void handle_user_read(const boost::system::error_code& err,std::size_t bytes_transferred) { } void handle_accept(tcp_connection::pointer new_connection,const boost::system::error_code& error) { if (!error) { new_connection->start(); start_accept(); } } tcp::acceptor acceptor_; }; 这是我的tcp连接: class tcp_connection : public boost::enable_shared_from_this<tcp_connection> { public: typedef boost::shared_ptr<tcp_connection> pointer; static pointer create(boost::asio::io_service& io_service) { return pointer(new tcp_connection(io_service)); } tcp::socket& socket() { return socket_; } void start() { // Start reading messages from the server start_read(); } public: tcp_connection(boost::asio::io_service& io_service) : socket_(io_service),timer_(io_service),io(io_service),timer2_(io_service) { } // Reading messages from the server void start_read() { boost::asio::async_read(socket_,input_buffer_,boost::asio::transfer_at_least(1),boost::bind(&tcp_connection::handle_read,shared_from_this(),boost::asio::placeholders::error)); timer_.expires_from_now(boost::posix_time::seconds(120)); timer_.async_wait(boost::bind(&tcp_connection::close,shared_from_this())); } void close() { cout<<"I didn't hear the client yet:closing the socket......"<<endl; socket_.close(); } // When stream is received,handle the message from the client int handle_read(const boost::system::error_code& ec) { if (!ec) { std::istream is(&input_buffer_); std::string line; std::getline(is,line); messageFromClient_+=line; messageFromClient_.erase(std::remove(messageFromClient_.begin(),messageFromClient_.end(),'n'),messageFromClient_.end()); std::size_t found = messageFromClient_.find(' '); if(found==std::string::npos) { boost::asio::async_read(socket_,boost::asio::placeholders::error)); } else{ performmaj();--my logic never mind. std::cout << "Request: "<<i<<" is on process......"<<"n";--mylogic boost::asio::ip::tcp::no_delay option(true); socket_.set_option(option); write(); messageToClient_="";--my logic. boost::system::error_code tc; socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_send,tc); } std::cout << "Request: "<<i<<" completed"<<"n"; ++i; (boost::asio::io_service io); }else { std::cout << "Error on receive: " << ec.message() << "n"; } } void write() { try{ boost::asio::write(socket_,boost::asio::buffer(messageToClient_),boost::asio::transfer_at_least(messageToClient_.size())); }catch(exception e) { cout<<e.what()<<endl; socket_.close(); io.run(); } } 请查看我使用async_write的下面的代码;请注意我有意写的字符串大小:11279204.但是在下面的代码中使用async_write让我的客户端接收更多部分但不完整的meaasage. class tcp_connection : public boost::enable_shared_from_this<tcp_connection> { public: typedef boost::shared_ptr<tcp_connection> pointer; static pointer create(boost::asio::io_service& io_service) { return pointer(new tcp_connection(io_service)); } tcp::socket& socket() { return socket_; } void start() { // Start reading messages from the server start_read(); } public: tcp_connection(boost::asio::io_service& io_service) : socket_(io_service),timer2_(io_service) { //io=io_service; } // Reading messages from the server void start_read() { boost::asio::async_read(socket_,boost::asio::placeholders::error)); } else{ performmaj(); cout<<messageToClient_.size()<<endl;--11279204 try{ boost::asio::async_write(socket_,boost::asio::buffer(messageToClient_.data(),messageToClient_.size()),// boost::asio::transfer_at_least(messageToClient_.size()),boost::bind(&tcp_connection::handle_write,boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred)); }catch(exception e) { Shutdown(); } } std::cout << "Request: "<<i<<" completed"<<"n"; ++i; return 0; }else { std::cout << "Error on receive: " << ec.message() << "n"; } } void Shutdown() { try { socket_.shutdown(socket_.shutdown_both); socket_.close(); } catch (std::exception &e) { std::cout << "Error Closing Socket" << e.what() << std::endl; } } void performmaj() { std::size_t found = messageFromClient_.find(' '); if (found!=std::string::npos) { std::cout << "Request: "<<i<<" Recieved"<<"n"; std::cout << "Request: "<<i<<" is on process......"<<"n"; if (messageFromClient_.size () > 0) messageFromClient_.resize (messageFromClient_.size () - 1); messageToClient_=test(messageFromClient_); messageFromClient_=""; messageToClient_.erase(std::remove(messageToClient_.begin(),messageToClient_.end(),messageToClient_.end()); } } void handle_write(const boost::system::error_code& ec,size_t bytes_transferred) { boost::asio::async_write(socket_,bytes_transferred),// boost::asio::transfer_at_least(bytes_transferred),bytes_transferred)); boost::system::error_code tc; socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_send,tc); } tcp::socket socket_; std::string messageToClient_; boost::asio::streambuf input_buffer_; std::string messageFromClient_; boost::asio::io_service& io; boost::asio::deadline_timer timer_,timer2_; }; 上面async_write的不可预知的行为导致我使用asio :: write. 解决方法
boost :: asio :: write()会阻塞,直到写入数据或抛出异常. write()函数捕获异常,关闭套接字并返回,但不表示套接字已关闭.然后在关闭的套接字上调用shutdown.创建关机功能.在write()中捕获丢弃异常错误但等待在Write()调用后调用Shutdown.您的逻辑总是在写入好或坏时调用Shutdown().也不要调用io.run().您的io_service()已在运行.
Shutdown() { try { socket_.shutdown(socket_.shutdown_both); socket_->close(); } catch (std::exception &e) { std::cout << "Error Closing Socket" << e.what() << std::endl; } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |