toLocal8bit通过TCP发送

时间:2018-01-19 14:55:42

标签: 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中的数据 - >写入(data,sizeof(data));正确发送到服务器,但当服务器回应它时,它看起来像&#34; something / x00 / x00 / x00 / x00&#34;或类似的东西。当我做这样的事情时:

#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";
    }
}

并且像你可以假设的那样,虽然我发送了&#34; wanlogin&#34;消息,服务器接收类似&#34; wanlogin / x00 / x00&#34;这显然会返回false。

此垃圾邮件应用于数据末尾,这无法检查发送的邮件。另一件事是发送数据的最大大小是8个字符,但也应用了这个长度垃圾的数据,所以它看起来像&#34; wanlogin / x00 / x00&#34 ;;但是,当我输入更多字符时,例如10,发送数据只会被剪切为8个符号,没有/ x00s。

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

1 个答案:

答案 0 :(得分:2)

sizeof(data)48,具体取决于您使用的是32位还是64位计算机。它是数据的大小,而是指针的大小(以字节为单位)。

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

解决方案是使用strlen()代替sizeof。或者,更好的是,通过将write()更改为QByteArray来直接使用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);
        ...
    }
    ...
}