在boost::asio中有火和忘记udp套接字的方法安全吗?
所以如果我有这样的代码
socket.async_send(buffer(somedata1),write_handler);
socket.async_send(buffer(somedata2),write_handler);
socket.async_send(buffer(somedata3),write_handler);
socket.async_send(buffer(somedata4),write_handler);我是否保证这不会失败--这意味着在接收端点,我将得到4个包含somedata1、somedata2、somedata3、somedata4的数据包?
发布于 2013-10-28 17:09:07
不,这肯定是不安全的,asio async_*函数的async_*none被记录为“失火和遗忘”。
用于发送缓冲区的boost asio引用声明:“虽然缓冲区对象可能在必要时被复制,但底层内存块的所有权由调用方保留,这必须保证它们在调用处理程序之前仍然有效。”
如果您需要“触发和忘记”方法,那么您将需要一个类来管理连接并为您缓冲数据包。下面是一个使用deque缓冲数据包的示例:
class Connection : public boost::enable_shared_from_this<Connection>
{
boost::asio::ip::udp::socket socket_;
std::deque<std::vector<char> > tx_queue_;
/// transmit the packet at the head of the queue
void transmit()
{
socket_.async_send(
boost::asio::buffer(&tx_queue_.front()[0], tx_queue_.front().size()),
boost::bind(&Connection::write_callback,
boost::weak_ptr<Connection>(shared_from_this()),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
/// The function called whenever a write event is received.
void write_handler(boost::system::error_code const& error,
size_t /* bytes_transferred */)
{
tx_queue_.pop_front();
if (error)
; // handle the error, it may be a disconnect.
else
if (!tx_queue_.empty())
transmit();
}
/// Static callback function.
/// It ensures that the object still exists and the event is valid
/// before calling the write handler.
static void write_callback(boost::weak_ptr<Connection> ptr,
boost::system::error_code const& error,
size_t bytes_transferred)
{
boost::shared_ptr<Connection> pointer(ptr.lock());
if (pointer && (boost::asio::error::operation_aborted != error))
pointer->write_handler(error, bytes_transferred);
}
/// Private constructor to enusure the class is created as a shared_ptr.
explicit Connection(boost::asio::io_service& io_service) :
socket_(io_service),
tx_queue_()
{}
public:
/// Factory method to create an instance of this class.
static boost::shared_ptr<Connection> create(boost::asio::io_service& io_service)
{ return boost::shared_ptr<Connection>(new Connection(io_service)); }
/// Destructor, closes the socket to cancel the write callback
/// (by calling it with error = boost::asio::error::operation_aborted)
/// and free the weak_ptr held by the call to bind in the transmit function.
~Connection()
{ socket_.close(); }
/// add the packet to the end of the queue and send it ASAP.
#if defined(BOOST_ASIO_HAS_MOVE)
void send(std::vector<char>&& packet)
#else
void send(const std::vector<char>& packet)
#endif
{
bool queue_empty(tx_queue_.empty());
tx_queue_.push_back(packet);
if (queue_empty)
transmit();
}
};https://stackoverflow.com/questions/19633544
复制相似问题