为了测试我的服务器,我已经使用来自客户端的for循环创建了100个请求,而我的服务器正在为第N个请求编写响应,我故意从客户端按下control + 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('\0');
if(found==std::string::npos)
{
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));
}
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),timer_(io_service), io(io_service),timer2_(io_service)
{
//io=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('\0');
if(found==std::string::npos)
{
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));
}
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, shared_from_this(),
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('\0');
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(), '\n'), messageToClient_.end());
}
}
void handle_write(const boost::system::error_code& ec,
size_t bytes_transferred)
{
boost::asio::async_write(socket_,boost::asio::buffer(messageToClient_.data(),bytes_transferred),
// boost::asio::transfer_at_least(bytes_transferred),
boost::bind(&tcp_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
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。
答案 0 :(得分:1)
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;
}
}