我正在编写一个简单的网络应用程序。客户端发送到服务器消息服务器在QTextEdit中打印它并响应客户端。 我正在使用QTcpServer和QTcpSocket。 有一个问题我无法解决。接收数据是quint16 + QTime + QString,它作为QByteArrey发送。 我使用quint16来接收数据块的大小。并且由于某种原因,客户端发送到服务器
next block size: 16 (quint16 value)
block size: 18
服务器获取:
next block size: 30073 (quint16 value)
block size: 18
正如您所看到的,由于某种原因,服务器从QDataStrem获取错误的变量值,它总是30073.我不明白为什么?
void Widget::slotSendToServer()
{
logTextEdit->append("slotSendToServer()");
QByteArray arrBlock;
QDataStream serverSendStream(&arrBlock, QIODevice::ReadWrite);
QString messageStr = messageLineEdit->text();
serverSendStream << quint16(0) << QTime::currentTime()
<< messageStr;
serverSendStream.device()->seek(0);
serverSendStream << (quint16)(arrBlock.size() - sizeof(quint16));
qDebug() << "next_block_size:"
<<(quint16)(arrBlock.size() - sizeof(quint16))
<< endl
<< "full size of Byte arrey:" << arrBlock.size();
tcpSocket->write(arrBlock);
messageLineEdit->clear();
}
void Widget::slotReadClient()
{
logTextEdit->append("slotReadClient()");
QTcpSocket *tcpSocket = (QTcpSocket*)sender();
QDataStream clientReadStream(tcpSocket);
while(true)
{
if (!next_block_size)
{
if (tcpSocket->bytesAvailable() < sizeof(quint16))
{
break;
}
clientReadStream >> next_block_size;
}
if (tcpSocket->bytesAvailable() < next_block_size)
{
break;
}
QTime time;
QString messageTextStr;
clientReadStream >> time >> messageTextStr;
QString messageCompleteStr =
time.toString() + " " + "Client has sent - "
+ messageTextStr;
logTextEdit->append("Message received: ");
logTextEdit->append(messageCompleteStr);
next_block_size = 0;
sendToClient(tcpSocket,
"Server Response: Received \""
+ messageTextStr + "\"");
}
}
答案 0 :(得分:2)
每次连接套接字时,应确保变量next_block_size
初始化为0.
如果您不重复使用相同的QTcpSocket
对象,则可以在Widget
类构造函数中执行此操作,或者如果执行此操作,则可以在连接到信号connected()
的插槽中执行此操作。< / p>
答案 1 :(得分:-1)
我不知道你为什么这么复杂。 这应该有效:
void Widget::slotSendToServer()
{
logTextEdit->append("slotSendToServer()");
QByteArray arrBlock;
QDataStream serverSendStream(tcpSocket);
serverSendStream << QTime::currentTime()
<< messageLineEdit->text();
messageLineEdit->clear();
}
void Widget::slotReadClient()
{
logTextEdit->append("slotReadClient()");
QTcpSocket *tcpSocket = (QTcpSocket*)sender();
QDataStream clientReadStream(tcpSocket);
QTime time;
QString message;
clientReadStream >> time >> message;
emit YourSignal(time, message);
}
您不必担心大小,QDataStream会跟踪它,您只需要保持与写入时相同的读取顺序,因此您的缓冲区arrBlock
会浪费代码。
关于你的代码,你确实把你的阅读器搞砸了while循环,所以这里有没有这个循环的修正。
void Widget::slotReadClient()
{
logTextEdit->append("slotReadClient()");
QTcpSocket *tcpSocket = (QTcpSocket*)sender();
QDataStream clientReadStream(tcpSocket);
if (next_block_size==0) {
// need to read data size
if (tcpSocket->bytesAvailable() < sizeof(quint16))
return; // wait for next signal
// next_block_size must be type of qint16
clientReadStream >> next_block_size;
}
if (tcpSocket->bytesAvailable() < next_block_size) {
// not enought data to complete read immediately
return; // wait for next signal
}
QTime time;
QString messageTextStr;
clientReadStream >> time >> messageTextStr;
QString messageCompleteStr =
time.toString() + " " + "Client has sent - "
+ messageTextStr;
logTextEdit->append("Message received: ");
logTextEdit->append(messageCompleteStr);
// mark that data read has been finished
next_block_size = 0;
}