Редактировать: ваша ошибка в том, что вы открываете поток данных out
в режиме ReadOnly, но пытаетесь записать в него полученный массив байтов:
void Server::readyRead()
{
QByteArray block;
QDataStream out(&block, QIODevice::ReadOnly); // !mistake, WriteOnly mode is needed
out << tcpSocket->readAll(); // this is write operation
//...
}
Дополнительно: обратите внимание, что существует механизм сериализации данных Qt. Типы, которые полезны в таких случаях:
tSock->write(block); // this is write just a raw data of the block, not the "QByteArray"
Вы можете использовать потоковую операцию для записи необходимых типов данных Qt в сокет напрямую, без преобразования в QByteArray
:
// Connect firstly
tSock->connectToHost(ipAddress, portNumb.toInt());
tSock->waitForConnected();
// Then open a data stream for the socket and write to it:
QDataStream out(tSock, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << name; // write string directly without a convertion to QByteArray
// Then you may
tSock->flush();
На стороне клиента, а затем используйте аналогичную операцию потока на стороне сервера:
void Server::readyRead()
{
QString name;
QDataStream in(tcpSocket, QIODevice::ReadOnly /*or QIODevice::ReadWrite if necessary */);
in.setVersion(QDataStream::Qt_4_0);
in >> name; // read the string
//...
}
Также возможно читать/записывать объекты других устройств ввода-вывода Qt: QFile, QSerialPort, QProcess, QBuffer и другие.
Изменить 2: не гарантируется, что по сигналу readyRead
вы получите полный пакет, который был отправлен. Поэтому см. пример ниже.
Обратите внимание, что в реальном случае (когда у вас несколько разных пакетов в клиент-серверной коммуникации, и неизвестно, какой из нескольких возможных пакетов вы получили) обычно используется более сложный алгоритм, так как при событии readyRead в сообщении могут возникнуть следующие ситуации:
- Полный пакет получен
- Получил только часть посылки
- Получил несколько посылок вместе
Вариант алгоритма (Пример клиента Qt 4 Fortune):
void Client::readFortune() // on readyRead
{
QDataStream in(tcpSocket);
in.setVersion(QDataStream::Qt_4_0);
if (blockSize == 0) {
if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
return;
in >> blockSize;
}
if (tcpSocket->bytesAvailable() < blockSize)
return;
QString nextFortune;
in >> nextFortune;
//...
}
Qt 4.0 — слишком старая версия Qt, поэтому см. также Qt 5.9 Fortune Client Пример
person
Vladimir Bershov
schedule
13.06.2017