編輯:你的錯誤是,你打開只讀模式out
數據流,但要儘量寫接收的字節數組分配給它:
void Server::readyRead()
{
QByteArray block;
QDataStream out(&block, QIODevice::ReadOnly); // !mistake, WriteOnly mode is needed
out << tcpSocket->readAll(); // this is write operation
//...
}
附加條件:請注意,有這種情況下有用的Serialization mechanism of Qt Data Types:
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的I/O設備:QFile,QSerialPort,QProcess,QBuffer等。
編輯2:不保證在readyRead
信號你會收到完整的包發送。因此請參閱下面的示例。
請注意,在現實情況下(當你在客戶端 - 服務器通信的幾個不同的數據包,並且不知道什麼樣的,你已經收到了幾個可能的數據包的),通常有使用更復雜的算法,這是因爲下面的情況下,可能對在通信的readyRead事件發生:
- 全部分組接收到
- 僅接收到包的一部分
- 個收到幾個包一起
的算法的變體(Qt 4 Fortune Client Example):
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 Example
一般來說,一個插座上重新創建一個'QDataStream'或者是錯誤的,因爲你會失去流的狀態,並且可能會丟失數據以及。 –
@KubaOber,但這是Qt 4文檔中的一個例子,我確信上述'readFortune()'函數的代碼是正確的 –
它是正確的,但它會很快變得不正確修改它。 –