c++ - toLocal8bit 通过 TCP 发送

标签 c++ multithreading qt sockets tcp

我正在 QT Creator 框架中创建 TCP 服务器/客户端应用程序。我想从 UI 输入字段获取一些数据并通过 TCP 发送它。

我在客户端应用程序中做这样的事情:

 void MainWindow::on_btn_login_clicked()
{
    QByteArray text = (ui->login_input->text()).toLocal8Bit();
    char* out = text.data();
    connection->ConnectAndSendData(out);
}

在 ConnectAndSendData 函数中:

void TcpConnect::ConnectAndSendData(const char* data)
{
    socket = new QTcpSocket(this);
    int port = 1234;
    socket->connectToHost("localhost", port);

    if(socket->waitForConnected(3000))
    {
        qDebug() << "connected to s. localhost at port " << port;
        socket->flush();
        socket->write(data, sizeof(data));
        qDebug() << data << "\n";

        socket->waitForReadyRead();
        char* serverresponse;
        socket->read(serverresponse, 128);

        if(serverresponse == MESSAGE_LOGINRQ)
            socket->write(data);
        socket->flush();
        socket->close();
    }
    else
    {
        /**/
    }
}

和数据行 socket->write(data, sizeof(data));已正确发送到服务器,但当服务器回显它时,它看起来像“something/x00/x00/x00/x00”或类似的东西。另外当我做这样的事情时:

#define MESSAGE_WANTLOGIN "wanlogin"
socket->write(MESSAGE_WANTLOGIN, sizeof(MESSAGE_WANTLOGIN));

消息被那些空符号弄乱了。

在服务器端接收数据看起来很简单:

void Thread::readyRead()
{
    socket->flush();
    QByteArray data = socket->readAll();
    qDebug() << "data received: " << data;
    if(data == MESSAGE_WANTLOGIN)
    {
        socket->write(MESSAGE_LOGINRQ);
    } else
    {
        qDebug() << "error not messageloginrq";
    }
}

就像你可以假设的那样,虽然我发送了“wanlogin”消息,但服务器收到了类似“wanlogin/x00/x00”的信息,如果明显返回 false。

这个垃圾应用在数据的末尾,这不可能检查发送了什么信息。另一件事是发送数据的最大大小为 8 个字符,但也会对这种长度的数据应用垃圾,因此它看起来像“wanlogin/x00/x00”;然而,当我键入更多字符时,例如 10 个,发送数据被削减为 8 个符号,没有/x00s。

所以我的问题是如何从那些/x00 中清除数据以及如何发送超过 1 个字节的信息(我需要它,例如发送用户的登录名和密码)。对不起,如果有一些愚蠢的错误,它是我的第一个客户端/服务器应用程序,它也为每个客户端使用多线程。

最佳答案

sizeof(data)48 取决于您是在 32 位还是 64 位机器上。它不是数据的大小,而是指针的大小(以字节为单位)。

那么实际的 wanlogin 实际上是一个 6 字符的字符串,而您最终又发送了 2 个字节。在这种情况下,您很幸运:data() 返回的 char 数组以 null 结尾,因此您可以访问一个额外的 0,但访问第二个 0 是未定义的行为,即任何事情都可能发生。

解决方案是使用strlen()而不是 sizeof。或者,更好的是,通过将 ConnectAndSendData(const char* data) 更改为 ConnectAndSendData(const QByteArray &data).

void MainWindow::on_btn_login_clicked()
{
    const QByteArray text = (ui->login_input->text()).toLocal8Bit();
    connection->ConnectAndSendData(text);
}

void TcpConnect::ConnectAndSendData(const QByteArray & data)
{
    socket = new QTcpSocket(this);
    quint16 port = 1234;
    socket->connectToHost("localhost", port);

    if(socket->waitForConnected(3000))
    {
        qDebug() << "connected to s. localhost at port " << port;
        socket->write(data);
        ...
    }
    ...
}

关于c++ - toLocal8bit 通过 TCP 发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48343800/

相关文章:

Qt 5.8 Apple 通知服务器握手失败

c++ - 在 C++ 中实现访问者设计模式的错误

c++ - boost::lockfree::queue 正在耗尽我的 CPU

c++ - 为Qt项目的每个模块添加一个include

c# - 并发队列 C# 中的线程安全

javascript - 多个 Rhino (java) 线程操作同一个文件

c++构造函数发生故障

c++ - QProgressDialog : How to adjust the size of the dialog to fit its contents?

c++ - 声明一个非常大的整数 vector ?

c++ - 如何避免 protected 类成员?