QTcpServer с клиентом Android не может распечатать или использовать данные, полученные от клиента

Я занимаюсь разработкой клиент-серверного приложения на C++ с использованием инфраструктуры Qt, но клиентами могут быть телефоны и компьютеры Android (клиентское приложение Qt). Теперь у меня возникают проблемы с обработкой приема данных на стороне сервера; сервер не получает данные должным образом.

Во-первых, у меня все хорошо работает между сервером (приложение Qt) и клиентом (приложение Qt), используя эти методы для отправки и получения: размер сообщения сохраняется в начале пакета, чтобы помочь проверить, является ли сообщение целиком получил или нет.

Это способ отправки сообщения клиентам

void Server::send(const QString &message)
{
    QByteArray paquet;
    QDataStream out(&paquet, QIODevice::WriteOnly);

    out << (quint16) 0; // just put 0 at the head of the paquet to reserve place to put the size of the message
    out << message; // adding the message
    out.device()->seek(0); // coming back to the head of the paquet
    out << (quint16) (paquet.size() - sizeof(quint16)); // replace the 0 value by the real size


    clientSocket->write(paquet); //sending...

}

Этот слот вызывается каждый раз, когда принимается один пакет.

void Server::dataReceived()
{
    forever 
    {
        // 1 : a packet has arrived from any client

        // getting the socket of that client (recherche du QTcpSocket du client)
        QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
        if (socket == 0) 
            return; 

        QDataStream in(socket);

        if (dataSize == 0) // if we don't know the size of data we are suppose to receive...
        {
            if (socket->bytesAvailable() < (int)sizeof(quint16)) // we haven't yet receive the size of the data completly then return...
                 return;

            in >> dataSize; // now we know the amount of data we should get
        }

        if (socket->bytesAvailable() < dataSize) 
            return;

        // Here we are sure we got the whole data then we can startreadind
        QString message;
        in >> message;

        //Processing....

        dataSize = 0; // re-initialize for the coming data
    }
}

Это работает хорошо, когда сервер общается с клиентом приложения Qt, потому что там используются те же методы, и размер quint16 останется прежним, но он не работает с клиентом Android, тогда я попробовал другой способ, которым я хотел игнорировать размер отправленного сообщения, но форматировать сообщение таким образом, чтобы я мог знать, где оно начинается и где оно заканчивается, а затем с помощью некоторых элементов управления я могу получить его, однако я застрял здесь, потому что чтение данных не не содержит ничего при печати, но его размер имеет значение (которое может варьироваться в зависимости от объема текста, отправляемого клиентом)!

void Server::dataReceived() // a packet is received!
{

    QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
    if (socket == 0)
        return;


    QByteArray data= socket->readAll(); //reading all data available
    QString message(data)

    qDebug() << data;        // this prints nothing!
    qDebug() << data.size();//  But this prints a non null number, wich means we got something, and that number varies according to the amount of text sent!
    qDebug() << message;    // this also prints notghing!

} 

PS: это не работает даже для клиента приложения Qt.

Можете ли вы помочь мне выяснить, что не так, я немного запутался, как протокол tcp обрабатывает данные, и если вы могли бы и посоветовать мне хороший способ сделать это.

вот класс андроид, который я сделал для этой цели

class QTcpSocket implements Runnable {

    private String ip="";
    private int port;
    private Socket socket;
    private PrintWriter printWriter;

    private DataOutputStream dataOutputStream;
    private DataInputStream dataInputStream;

    public QTcpSocket(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }

      public void setIp(String ip) {
          this.ip = ip;
      }

      public String getIp() {
          return this.ip;
      }

    public void setPort(int port) {
        this.port = port;
    }

    public void run() {
        try {
            socket = new Socket(this.ip, this.port);
            dataOutputStream = new DataOutputStream( socket.getOutputStream() );
            dataInputStream = new DataInputStream(socket.getInputStream());
            String response = dataInputStream.readUTF();
            dataOutputStream.writeUTF("Hello server!");


        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void sendMessage(String message) {
        try {

            dataOutputStream.writeUTF(message);
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void disconnect() {
        try {

            printWriter.flush();
            printWriter.close();
            socket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean isClosed() {
        return socket.isClosed();
    }
}

1 ответ

Решение

Замените в "data" все байты значением 0 на значение 20 и напечатайте снова. Я думаю, что вы ничего не напечатали, потому что первый байт равен 0. Вы также можете заменить на 'X'. Вы уже заменили writeUTF() на write ()?

20 - это символ пробела. Но тогда вы также не видите ничего напечатанного, так что лучше используйте X char. Строки печатаются до тех пор, пока не будет достигнут символ \0 (который указывает на конец строки). Поскольку ничего не было напечатано, я предположил, что один в самом начале. Так что writeUTF приводит к тому, что ведущий 0. Я мог бы объяснить это, только если все символы удвоились. Каким был первый символ, который вы послали?

Но теперь: сначала отправьте размер сообщения, чтобы он равнялся вашему клиенту qt.

Другие вопросы по тегам