【问题标题】:boost::asio::async_write with std::stringboost::asio::async_write 与 std::string
【发布时间】:2017-12-09 17:51:05
【问题描述】:

所以我的设置如下:

  • Raspberry Pi 作为 TCP 服务器使用 boost asio c++ 库;
  • TCP 客户端在其他机器上运行;

通信工作正常,预计我应该能够向客户请求发送答案。为此,我使用以下代码:

std::cout << "\tI2C message from Arduino: " << I2CrxBuf_;
boost::asio::async_write(sock_, boost::asio::buffer( I2CrxBuf_.c_str(), sizeof(I2CrxBuf_.c_str()) ), boost::bind(&conn::h_write, shared_from_this()));
std::cout << "Passei o async_write" << std::endl;

问题是消息打印得很好,但随后它跳到最后一个打印而不将消息发送给客户端,因此客户端阻塞。

服务器中的输出如下:

I2C message from Arduino: l 1 14.88
Passei o async_write

如果我发送这样的通用消息:

boost::asio::async_write(sock_, boost::asio::buffer( "Message recevied\n" ), boost::bind(&conn::h_write, shared_from_this()));

客户端按预期收到消息。

我很确定问题与我将字符串转换为 char* 的方式有关,但我没有找到让它工作的方法。

【问题讨论】:

  • sizeof(I2CrxBuf_.c_str()) 是 4 个字节。我想你的意思是I2CrxBuf_.size()
  • 谢谢,那是真的,但仍然没有发送...
  • 我也检查过 c.str() 方法没有从字符串末尾删除 '\n '。由于客户端需要消息才能拥有它,这应该不是问题。
  • 不太确定我是否理解问题,但是......从std::string::c_str 返回的值应该被视为临时值,因此不适合传递给异步函数,例如async_write。如果I2CrxBuf_ 在范围内并且在写入操作期间未修改,则只需使用它构造缓冲区--boost::asio::buffer(I2CrxBuf_)
  • 抱歉@arrowd 这确实是问题所在。

标签: c++ multithreading boost-asio tcpserver condition-variable


【解决方案1】:

sizeof(I2CrxBuf_.c_str()) 是错误的。另外,你可以直接做buffer(I2CrxBuf)。有关其他重载,请参阅 docs

除此之外,请注意字符串 需要 保持活动状态直到异步操作结束(同时不能修改)。

文档中的所有示例对如何实现这一点都有很好的想法。

【讨论】:

  • 谢谢!我有互斥锁以确保它不会被修改...但无论如何感谢您的警告!
  • Mutex 不能真正在异步设置中工作。当然它可以如果你跳过箍,确保所有处理程序在特定线程上运行并且你保持互斥锁长时间锁定(所有这些都是设计气味) - 我真的认为我们可以90% 确定您的互斥锁方法存在缺陷。你如何让字符串保持活力?看Asio Strands关于数据/资源同步
  • 对不起,在这种情况下,我正在使用 condition_variable... 他们应该可以完成这项工作吗?
  • 没有区别。 condition_variable 表示锁定原语。我很高兴查看真实代码。如果您还没有听说过这个网站:Code Review
  • 这里的问题是,当我在另一个线程上获得客户端请求的答案时,我需要停止服务器。有更好的方法吗?顺便说一句,感谢您提供的链接,我会检查一下。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 2012-08-12
  • 2021-03-01
  • 1970-01-01
  • 2017-01-08
相关资源
最近更新 更多