c++ - boost::asio::async_write 以\0 开头的字符串到达​​另一边

标签 c++ boost boost-asio

我不是 boost 专家,我正在尝试使用 boost::asio。一切都很好,直到我把事情搞砸了。不幸的是我不确定我做了什么... =P

这是发生了什么:

我有一个服务器,它是一个 C++ Builder 应用程序,它打开一个套接字,我的客户端应用程序 (Visual Studio C++ DLL) 连接到该套接字。

当我尝试向套接字写入内容时,我没有收到任何错误,但服务器收到这样的字符串:“\0SomeText”。我不知道\0 从哪里来。

下面是一些可能会解决问题的代码:

    void CometClient::SendCommand()
{
    if (socket_.is_open())
    {
        TCommands::iterator it = pending_commands.begin();
        while (it != pending_commands.end())
        {
            std::vector<char> vctCommand;
            vctCommand.assign((*it).begin(), (*it).end());
            vctCommand.push_back('\n');
            boost::shared_ptr<std::vector<char> > ptr_command = boost::make_shared<std::vector<char> > (vctCommand);

            boost::asio::async_write(socket_, boost::asio::buffer( *ptr_command ) ,
                boost::bind(&CometClient::handle_write_request, this,
                    boost::asio::placeholders::error, ptr_command )
                );
            it = pending_commands.erase(it);
        }

    }
    else
    {
        // Something
    }
}

void CometClient::handle_write_request(const boost::system::error_code& err, boost::shared_ptr< std::vector<char> > command)
{
    if (!err)
    {
        std::vector<char> * ptr = command.get();
        boost::asio::async_read_until(socket_, response_, "\n",
            boost::bind(&CometClient::handle_read_content, this,
            boost::asio::placeholders::error));
    }
    else
    {
        // Something
    }
}

任何帮助将不胜感激。

提前致谢!

编辑:

这是我在 janm 回答后得到的:

    void CometClient::SendCommand()
{
    // bConnected tells me if the server has already answered me and Connected just tells me if the socket is open (will change in the near future)
    if (Connected() && pending_commands.size() && bConnected)
    {
        std::vector<char> vctCommand;
        std::string sCommand(pending_commands.front().c_str());
        pending_commands.pop_front();
        vctCommand.assign(sCommand.begin(), sCommand.end());
        vctCommand.push_back('\n');
        boost::shared_ptr<std::vector<char> > ptr_command = boost::make_shared<std::vector<char> > (vctCommand);

        boost::asio::async_write(socket_, boost::asio::buffer( *ptr_command, sCommand.length() ) ,
            boost::bind(&CometClient::handle_write_request, this,
            boost::asio::placeholders::error, ptr_command )
            );
    }
    else
    {
        // Something
    }
}

void CometClient::handle_write_request(const boost::system::error_code& err, boost::shared_ptr< std::vector<char> > command)
{
    if (!err)
    {
        std::vector<char> * ptr = command.get();
        boost::asio::async_read_until(socket_, response_, "\n",
            boost::bind(&CometClient::handle_read_content, this,
            boost::asio::placeholders::error));
        SendCommand();
    }
    else
    {
        // Something
    }
}

最佳答案

您正在生成对 async_write() 的多个并发调用。不保证这些调用是原子的或顺序的。原因是async_write()是通过多次调用async_write_some()来实现的,调用者必须确保只有一次async_write() 和以往一样进行中。

更好的方法是从队列中取出第一个命令,然后在完成处理程序中启动下一个写入。这可能是您意想不到的虚假字节的原因。

要检查的另一件事是您的载体是否确实包含您认为它们包含的内容。使用调试器或发出的日志输出进行检查。

关于c++ - boost::asio::async_write 以\0 开头的字符串到达​​另一边,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17458998/

相关文章:

c++ - 使用 "using"两次被不同的编译器以不同方式解释

c++ - 使用 boost 序列化 std::unordered_map < int, std::unordered_set<int>>

c++ - 如何在 Xcode 9.0 中使用 OpenMP

c++ - 版本 `CXXABI_1.3.8' 未找到(...需要)

c++ - 如何将 C++ boost posix_time::ptime 的分辨率更改为毫秒?

c++ - 在 linux 中使用 boost xml_parser 如何读取和比较 windows-1251 文字?

c++ - 为什么我无法访问类 'boost::asio::detail::noncopyable' 中声明的私有(private)成员?

c++ - 如何确定哪个兄弟收到事件?

c++ - boost::make_shared 失败但 std::make_shared 工作

c++ - Boost 的 ASIO 和隐藏那些棘手的 io_service 对象