我无法使用 Qt 和 Boost 通过网络发送标头大小

发布于 2024-12-17 23:14:57 字数 1838 浏览 4 评论 0原文

我尝试将类的大小从 Qt 客户端发送到 Boost 服务器(我都做了)。

这是我想要序列化的类

class Commande
{
public:
        std::string     login;
        std::string     mdp;
        std::string     IP;
        std::string     to;
        std::string     from;
        bool            rep;
        int             nbCmd;
};

这是我用来序列化和发送 Commande 大小和对象的函数。 _socket 是一个 QTcpSocket

void    BNetwork::sendData(void)
{
    QByteArray  paquet;
    QDataStream out(&paquet, QIODevice::WriteOnly);
    Commande    cmd;

    cmd.setCmd(1);
    cmd.setFrom("Paris");
    cmd.setIP("127.0.0.1");
    cmd.setLogin("test1");
    cmd.setMdp("mdp1");
    cmd.setRep(0);
    cmd.setTo("maryline");
    out << (quint32) 0;
    out << cmd;
    out.device()->seek(0);
    out << (paquet.size() - (int)sizeof(quint32));
    this->_socket.write(paquet);
}

QDataStream &operator<<(QDataStream &out, Commande &cmd)
{
    QString test(cmd.from.c_str());

        out << (quint32)cmd.nbCmd;
        out << test;
        test = cmd.IP.c_str();
        out << test;
        test = cmd.mdp.c_str();
        out << test;
        out << (quint32)cmd.rep;
        test = cmd.to.c_str();
        out << test;
        return out;
}

这是我用来转换从 QT 客户端收到的标头大小的函数。

std::string  save = this->connection->getIheader(); \\ this is the string i read on the socket
std::istringstream                      stream(save);
std::cout << save << std::endl;
if (!(stream >> std::dec >> this->Isize))
      throw my_exception("error in endRead()");

由于未知原因,save 包含“1000”,当我尝试将此字符串转换为整数时,它不起作用,所以我认为我得到的值不正确。

客户端和服务器运行在windows 7 64位上。

你有办法解决我的问题吗?

I try to send a class' size from a Qt client to a Boost server (I made both).

This is the class I want to serialize

class Commande
{
public:
        std::string     login;
        std::string     mdp;
        std::string     IP;
        std::string     to;
        std::string     from;
        bool            rep;
        int             nbCmd;
};

This is the function I use to serialize and send the Commande size and the object.
_socket is a QTcpSocket

void    BNetwork::sendData(void)
{
    QByteArray  paquet;
    QDataStream out(&paquet, QIODevice::WriteOnly);
    Commande    cmd;

    cmd.setCmd(1);
    cmd.setFrom("Paris");
    cmd.setIP("127.0.0.1");
    cmd.setLogin("test1");
    cmd.setMdp("mdp1");
    cmd.setRep(0);
    cmd.setTo("maryline");
    out << (quint32) 0;
    out << cmd;
    out.device()->seek(0);
    out << (paquet.size() - (int)sizeof(quint32));
    this->_socket.write(paquet);
}

QDataStream &operator<<(QDataStream &out, Commande &cmd)
{
    QString test(cmd.from.c_str());

        out << (quint32)cmd.nbCmd;
        out << test;
        test = cmd.IP.c_str();
        out << test;
        test = cmd.mdp.c_str();
        out << test;
        out << (quint32)cmd.rep;
        test = cmd.to.c_str();
        out << test;
        return out;
}

This is the function I use to convert the header size I received from the QT client.

std::string  save = this->connection->getIheader(); \\ this is the string i read on the socket
std::istringstream                      stream(save);
std::cout << save << std::endl;
if (!(stream >> std::dec >> this->Isize))
      throw my_exception("error in endRead()");

For an unknown reason, save contains "1000", and when I try to convert this string into an integer, it's not working so I think the value I get isn't correct.

The client and the server are running on windows 7 64bits.

Do you have a solution to my problem?

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

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

发布评论

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

评论(1

浊酒尽余欢 2024-12-24 23:14:57

首先,确认当您使用 out.device()->seek(0) 时,您会导致下一个写入按照您的预期前置,而不是覆盖您已经写入的数据,如下所示我预计。

然后,针对很可能存在相同或类似问题的问题查阅此答案

如果您需要更多帮助,请在评论中告诉我。

ETA:QString将数据存储为16位QChar,以支持unicode。 std::stringstd::istringstream 正在读取 8 位char。另请参阅此答案。由 QT 序列化的 QChar 可能会给您带来麻烦。另请注意,getIheader() 返回的字符序列中出现的任何 0(空)字符都将终止 std::string 的赋值运算符。

我建议将 std::istringstream 替换为 QDataStream,并使用该类将数据读出为您最初编写的类型。在将序列化抛在脑后之后,您可以从 QT 类型转换为 C++ 本机类型。否则,您将必须非常小心地弄清楚 QT 在幕后正在做什么?通过你自己的努力来匹配它。

First, confirm that when you use out.device()->seek(0), you cause the next writes to prepend as you expect, rather than overwriting the data you've already written, as I expect.

Then, consult this answer to a question that very likely has the same or similar problem.

Let me know in a comment if you need more help.

ETA:QStringstores data as 16 bitQChar, in order to support unicode. std::stringandstd::istringstreamare reading 8 bitchar. See also this answer. The QChars serialized by QT are likely to cause you trouble down the line. Note also that any 0 (null) char that happens to be in the char sequence returned by getIheader() will terminate std::string's assignment operator.

I recommend replacing thestd::istringstreamwith aQDataStream, and using that class to read out your data to exactly the types you originally wrote. You can cast from QT types to c++ native types after you've put serialization behind you. Otherwise, you'll have to take lots of care to figure out what QT is doing under the hood & match it by your own effort.

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