gpt4 book ai didi

boost - 延迟后未调用 async_write_some 回调

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

我对 async_write_some 的回调在一秒钟 sleep 后没有被调用。如果我为每次写入启动一个 io_service 工作线程,为什么没有调用回调?

标题

boost::system::error_code error_1;
boost::shared_ptr <boost::asio::io_service> io_service_1;
boost::shared_ptr <boost::asio::ip::tcp::socket> socket_1;

连接

void eth_socket::open_eth_socket (void)
{
// 1. reset io services
io_service_1.reset();
io_service_1 = boost::make_shared <boost::asio::io_service> ();

// 2. create endpoint
boost::asio::ip::tcp::endpoint remote_endpoint(
boost::asio::ip::address::from_string("10.0.0.3"),
socket_1_port
);

// 3. reset socket
socket_1.reset(new boost::asio::ip::tcp::socket(*io_service_1));

// 4. connect socket
socket_1->async_connect(remote_endpoint,
boost::bind(
&eth_socket::socket_1_connect_callback,
this, boost::asio::placeholders::error
)
);

// 5. start io_service_1 run thread after giving it work
boost::thread t(boost::bind(&boost::asio::io_service::run, *&io_service_1));
return;
}

void eth_socket::write_data (std::string data)
{
// 1. check socket status
if (!socket_1->is_open())
{
WARNING << "socket_1 is not open";
throw -3;
}

// 2. start asynchronous write
socket_1->async_write_some(
boost::asio::buffer(data.c_str(), data.size()),
boost::bind(
&eth_socket::socket_1_write_data_callback,
this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);

// 3. start io_service_1 run thread after giving it work
boost::thread t(boost::bind(&boost::asio::io_service::run, *&io_service_1));
return;
}

回调

void eth_socket::socket_1_write_data_callback (const boost::system::error_code& error, size_t bytes_transferred)
{
// 1. check for errors
if (error)
{
ERROR << "error.message() >> " << error.message().c_str();
return;
}
if (socket_1.get() == NULL || !socket_1->is_open())
{
WARNING << "serial_port_1 is not open";
return;
}
INFO << "data written to 10.0.0.3:1337 succeeded; bytes_transferred = " << bytes_transferred;
return;
}

测试

open_eth_socket();
write_data("Hello"); // callback called
write_data("Hello"); // callback called
write_data("Hello"); // callback called
sleep(1);
write_data("Hello"); // callback not called after sleep

最佳答案

boost::thread t(boost::bind(&boost::asio::io_service::run, *&io_service_1));                

出于多种原因,这很奇怪。

我会添加这些顶级问题

  • 使用像 socket_1 这样的名称的味道(只需将其命名为 socket_ 并实例化另一个具有描述性名称的对象以包含另一个 socket_) .我不确定,但这个问题确实让人怀疑这些甚至可能是全局变量。 (我希望不是这样)
  • throw-ing 原始整数,真的吗?
  • 您在破坏 io_service 而从不检查工作线程是否已完成时冒着完全数据争用的风险。
  • 更多 Undefined Behaviour这里:

    _sock.async_write_some(
    ba::buffer(data.c_str(), data.size()),

    您传递了对超出范围的参数 data 的引用。当异步操作完成时,它将是一个悬挂引用

  • 这里存在一些明显的复制/粘贴问题:

    if (socket_1.get() == NULL || !socket_1->is_open())
    {
    WARNING << "serial_port_1 is not open";
    return;
    }

    我实际上会说这源于导致变量名称为 serial_port_1socket_1

  • 的完全相同的来源

一些清理

简化。没有独立的代码,所以这里没有什么是完整的,但至少可以看到许多简化点:

Live On Coliru

#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <iostream>

namespace ba = boost::asio;
using ba::ip::tcp;
using boost::system::error_code;

#define ERROR std::cerr
#define WARNING std::cerr
#define INFO std::cerr

struct eth_socket {

~eth_socket() {
_work.reset();
if (_worker.joinable())
_worker.join(); // wait
}

void open(std::string address);
void write_data(std::string data);

private:
void connected(error_code error) {
if (error)
ERROR << "Connect failed: " << error << "\n";
else
INFO << "Connected to " << _sock.remote_endpoint() << "\n";
}
void written(error_code error, size_t bytes_transferred);

private:
ba::io_service _svc;
boost::optional<ba::io_service::work> _work{ _svc };
boost::thread _worker{ [this] { _svc.run(); } };

std::string _data;

unsigned short _port = 6767;
tcp::socket _sock{ _svc };
};

void eth_socket::open(std::string address) {
tcp::endpoint remote_endpoint(ba::ip::address::from_string(address), _port);

_sock.async_connect(remote_endpoint, boost::bind(&eth_socket::connected, this, _1));
}

void eth_socket::write_data(std::string data) {
_data = data;

_sock.async_write_some(ba::buffer(_data), boost::bind(&eth_socket::written, this, _1, _2));
}

void eth_socket::written(error_code error, size_t bytes_transferred) {
INFO << "data written to " << _sock.remote_endpoint() << " " << error.message() << ";"
<< "bytes_transferred = " << bytes_transferred << "\n";
}

int main() {
{
eth_socket s;
s.open("127.0.0.1");

s.write_data("Hello"); // callback called
s.write_data("Hello"); // callback called
s.write_data("Hello"); // callback called
boost::this_thread::sleep_for(boost::chrono::seconds(1));
s.write_data("Hello"); // callback not called after sleep

} // orderly worker thread join here
}

关于boost - 延迟后未调用 async_write_some 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47332035/

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