使用 boost::asio read_some() 函数时替代 std::array,boost::array 在 read_some() 函数调用时崩溃

Posted

技术标签:

【中文标题】使用 boost::asio read_some() 函数时替代 std::array,boost::array 在 read_some() 函数调用时崩溃【英文标题】:Substitute for std::array when using boost::asio read_some() function, boost::array crashes at read_some() function call 【发布时间】:2014-08-07 15:19:54 【问题描述】:

我正在使用 boost 的套接字和 char 数组从套接字读取中读取结果。根据我在网上看到的示例(包括 Boost 文档),到目前为止我有这个:

#include <boost/asio.hpp>
#include <array>
#include <string>
#define MAXSIZE 1000000
//...
void MyClass::processCommand(std::string command)

  boost::asio::io_service io;
  boost::asio::ip::tcp::socket socket(io);
  boost::asio::ip::tcp::endpoint e(boost::asio::ip::address::from_string("127.0.0.1"), 60151);  //Info for the connection I need to make...
  this->socket.open(boost::asio::ip::tcp::v4());
  this->socket.connect(e);
  this->socket.write_some(boost::asio::buffer(command, command.size());
  this->socket.send(boost::asio::buffer(command, command.size());

  std::array<char, MAXSIZE> buffer;
  this->socket.read_some(boost::asio::buffer(buffer));

根据我看到的示例,这似乎应该可行。我有一个问题;无论出于何种原因,我的编译器(我在 Qt 5.2 中工作)似乎拒绝将 std::array 识别为有效。即使使用#include &lt;array> 行,定义缓冲区的行也会给出错误,指出数组不是std 的成员。我的项目负责人和我工作了一个小时左右,尝试了很多不同的方法来解决这个问题,包括完全重新安装 std 库,但无济于事;代码仍会将#include &lt;array> 行识别为有效,但不允许我使用std::array。我试图通过将缓冲区定义为char buffer[MAXSIZE] = "" 来解决这个问题,但是当它到达下一行的 read_some 命令时它会崩溃。诚然,我对使用 Boost 很陌生,我不确定是否有任何其他方法可以定义缓冲区以使其成为传递给 read_some 函数的有效参数。如果有人知道如何解决这个问题(如何将缓冲区传递给 read_some 而不会发生崩溃,或者如何让 std::array 工作),我将不胜感激。谢谢!

注意:我正在做的项目使用 VS2008。

UPDATE:到目前为止,除了上面示例代码中的代码,我还尝试了以下:

将缓冲区声明为char buffer[MAXSIZE]; 这可以编译,但程序在调用socket.read_some() 的行处冻结。我得到与char buffer[MAXSIZE] = ""; 相同的结果

将缓冲区声明为boost::array&lt;char, MAXSIZE> buffer;,无论是否添加包含boost/array.hpp 的指令行。这冻结在同一个地方。

根据我发现的here,尝试将缓冲区声明为std::tr1::array&lt;char, MAXSIZE> buffer;。同样按照相同的逻辑,我尝试添加using namespace std::tr1;,然后将缓冲区定义为array&lt;char, MAXSIZE> buffer;。这些都没有编译;由于参数类型不匹配,两者都在调用 read_some() 的行上出现错误。

我确实想到了,有可能,因为看起来应该工作的那些往往会冻结在read_some(),它需要很长时间才能阅读并且只是超时?如果是这种情况,我可以解决这个问题,我只是不知道如何判断这是正在发生的事情还是只是崩溃了。

【问题讨论】:

你必须使用c++11(类似-std=c++1)来#include &lt;array&gt; @juanchopanza 感谢您的回复,我尝试使用 boost::array 而不是 std::array,但它仍然在同一个地方崩溃:/ 怎么会崩溃?你声称它没有编译。 @juanchopanza 抱歉,如果这含糊不清,我的意思是 boost::array 代码与缓冲区 [MAXSIZE] = "" 的代码在同一点崩溃。它确实不像 std::array 那样编译 请不要编辑您的问题,一旦它被回答,使其成为(某种)新问题。 【参考方案1】:

应该没问题:看看吧Live On Coliru

#include <boost/asio.hpp>
#include <array>
#include <string>
#define MAXSIZE 1000000
//...
void processCommand(std::string command)

    boost::asio::io_service io;
    boost::asio::ip::tcp::socket socket(io);
    boost::asio::ip::tcp::endpoint e(boost::asio::ip::address::from_string("127.0.0.1"), 60151);  //Info for the connection I need to make...

    socket.open(boost::asio::ip::tcp::v4());
    socket.connect(e);
    socket.write_some(boost::asio::buffer(command));
    socket.send(boost::asio::buffer(command));

    std::array<char, MAXSIZE> buf;
    socket.read_some(boost::asio::buffer(buf));


int main()

    processCommand("EHLO");

如果您没有 C++11,请使用 boost::array(和 boost/array.hpp)。

在所有其他情况下,请在 Boost 问题跟踪器中查看您的编译器和潜在的不兼容报告

【讨论】:

我刚查了一下,我们的项目使用的是VS2008,所以看来我不能使用C++11。但是,当我为 boost/array.hpp 添加一个包含指令并将 std::array 更改为 boost::array 时,它会编译但在调用 read_some() 的行处崩溃。您是否知道可能导致该问题的原因?【参考方案2】:

您可以按照此处的建议使用 std::array boost::array std::vectorstd::string

http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/reference/buffer.html

【讨论】:

感谢您的回复,我尝试使用 boost::array 而不是 std::array 这似乎与该页面上的重载 11 匹配,但尽管它编译它在 read_some 行崩溃,您是否知道为什么会这样?此外,不幸的是我无法让 std::array 重载工作,它仍然告诉我 array 不是 std 的成员:/ 嗯,这是另一个问题,继续在它自己的线程中提问,提供尽可能多的细节来帮助确定发生了什么样的崩溃。

以上是关于使用 boost::asio read_some() 函数时替代 std::array,boost::array 在 read_some() 函数调用时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

BOOST中read_some和 boost::asio::error::eof错误

为啥在使用 boost::asio 时每个连接都需要 strand?

安全地完成读取操作 (Boost.Asio)

如何在 boost asio 中设置阻塞套接字的超时时间?

Boost ASIO,未调用 async_read_some 回调

Boost Asio总结(15)class basic_stream_socket