std::stringstream 错误?

发布于 2024-09-11 18:01:14 字数 2318 浏览 5 评论 0 原文

我有自己的 DLL,它被注入到另一个进程中。从其他进程,DLL 通过 boost::message_queue 到我的应用程序。我使用 std::stringstream 来构造消息,如下所示:

class Client
{
    ...

    private:
        template <class T> void AddMessageParameter(const T &m)
        {
            _message &lt&lt m &lt&lt "|";
        }

        void SendMessage()
        {
            if (_mq && _message.str().length() < 1024) {
                // Do not send the same message again.

                if (_mq_last_sent_message != _message.str()) {
                    _mq_last_sent_message = _message.str();

                    try {
                        unsigned int tries = 0;

                        // Try send the message five times before giving up.

                        do {
                            if (_mq->try_send(_mq_last_sent_message.c_str(), _mq_last_sent_message.length(), 0))
                                tries = 5;
                            else
                                ::Sleep(128);

                            ++tries;
                        } while (tries < 5);
                    } catch (...) {
                        // TODO: Add log4cxx logging here for errors...
                    }
                }
            }

            // Clear the message for a new one.

            _message.seekp(0);
            _message.clear();
            _message.str(std::string());
        }

    private:
        std::stringstream _message;
        std::string _mq_last_sent_message;
        boost::shared_ptr<boost::interprocess::message_queue> _mq;
};

在 DLL 中,其中一个函数不断发送以下消息:

AddMessageParameter("CLIENT__TABLE__PLAYER_BANKROLL");
AddMessageParameter(window_handle);
AddMessageParameter(seat);
AddMessageParameter(s);

SendMessage();

现在这会生成一条类似 CLIENT_TABLE_PLAYER_BANKROLL|00211606|6|€1.28|.问题是,在每几千条消息中,第一个参数不会添加到那里,并且消息变得像 00211606|6|€1.28|

这是为什么?这是 std::stringstream 中的一些错误还是我做错了什么?

预先感谢您的任何帮助。

编辑:

问题已解决。这是线程安全的问题。一个简单的互斥体解决了这个问题。

I've got my own DLL which is being injected into another process. From the other process, the DLL sends IPC messages via boost::message_queue to my application. I'm using std::stringstream to construct the messages, as following:

class Client
{
    ...

    private:
        template <class T> void AddMessageParameter(const T &m)
        {
            _message << m << "|";
        }

        void SendMessage()
        {
            if (_mq && _message.str().length() < 1024) {
                // Do not send the same message again.

                if (_mq_last_sent_message != _message.str()) {
                    _mq_last_sent_message = _message.str();

                    try {
                        unsigned int tries = 0;

                        // Try send the message five times before giving up.

                        do {
                            if (_mq->try_send(_mq_last_sent_message.c_str(), _mq_last_sent_message.length(), 0))
                                tries = 5;
                            else
                                ::Sleep(128);

                            ++tries;
                        } while (tries < 5);
                    } catch (...) {
                        // TODO: Add log4cxx logging here for errors...
                    }
                }
            }

            // Clear the message for a new one.

            _message.seekp(0);
            _message.clear();
            _message.str(std::string());
        }

    private:
        std::stringstream _message;
        std::string _mq_last_sent_message;
        boost::shared_ptr<boost::interprocess::message_queue> _mq;
};

In the DLL, one of the function sends the following message constantly:

AddMessageParameter("CLIENT__TABLE__PLAYER_BANKROLL");
AddMessageParameter(window_handle);
AddMessageParameter(seat);
AddMessageParameter(s);

SendMessage();

Now this produces a message like CLIENT_TABLE_PLAYER_BANKROLL|00211606|6|€1.28|. The problem is, that in every few thousand messages, the first parameter doesn't add there and the message becomes like 00211606|6|€1.28|

Why is that? Is this some bug in the std::stringstream or am I doing something wrong perhaps?

Thanks in advance for any help.

EDIT:

Problem solved. This was an issue of thread safeness. A simple mutex solved this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧夏天 2024-09-18 18:01:14

当尝试发送最长的消息时,您的代码失败。
因此我认为消息目标的读取速度不够快。

我认为你尝试 5 次的概念是有缺陷的,因为如果消息没有发送,你就会吞下消息 - 而且你甚至没有处理这个严重的错误情况。
就我个人而言,我建议要么永远等待发送消息,要么构建一个大小合理的本地缓冲区供您工作 - 如果该缓冲区已满,那么您将永远等待。

我还建议您不要在不照顾它们的情况下吃掉所有异常情况。你默默地隐藏了严重的错误。

作为旁注:
人们常常认为 std::string 有 bug,或者操作系统有 bug,甚至编译器有 bug。
让我向你保证,这些人的指控常常是错误的,即使是最具防御性的悲观主义者也会说他们总是错了。
那些正确的人可以在琐碎的程序中证明这一点。

请原谅我的傲慢。

Your code fails when trying to send the longest message.
Therefore I assume that the message target is not reading fast enough.

I think your concept of trying 5 times is flawed, because you swallow your message if it didn't got sent - and you don't even handle this serious error case.
Personally I recommend to either wait forever to send your message, or build a sane sized local buffer which you work of - and if this buffer is full, then you wait forever.

I also recommend that you don't eat all exceptions without caring for them. You silently hide serious errors.

As a side note:
People often think that std::string has bugs, or that the OS has bugs, or even that the compiler has bugs.
Let me assure you that these people are so often wrong in their accusation that even the most defensive pessimist would say that they are always wrong.
And those who are right can prove it in trivial programs.

Please excuse my arrogance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文