gpt4 book ai didi

c++ - 当服务器执行 asio::write 操作时客户端断开连接时 Boost TCP 服务器崩溃

转载 作者:可可西里 更新时间:2023-11-01 02:33:05 26 4
gpt4 key购买 nike

为了测试我的服务器,我从客户端使用 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 让我的客户收到更多部分但不完整的测量。

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。

最佳答案

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;
}
}

关于c++ - 当服务器执行 asio::write 操作时客户端断开连接时 Boost TCP 服务器崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31856233/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com