在学习QT的过程中,我写了一对很简单的TCP客户端和服务器端,监听绑定通信都正常,但是一旦断开连接重新连接,客户端接收的数据就会和截图里一样多出一些可能由空字符串或换行符之类导致的空白,而服务器端则一直能正常显示
如图所示
Server端发送数据函数:
void Widget::on_sendBt_clicked()
{
tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data());
}
接收函数:
void Widget::newConnection_Slot()
{
tcpSocket = tcpServer->nextPendingConnection();
connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readyRead_Slot()));
}
void Widget::readyRead_Slot()
{
QString buf;
buf = tcpSocket->readAll();
ui->recvEdit->appendPlainText(buf);
}
Client端发送数据函数:
void Widget::on_sendBt_clicked()
{
tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data());
}
接收函数:
void Widget::readyRead_Slot()
{
ui->recvEdit->appendPlainText(tcpSocket->readAll());
}
当我将客户端的接收数据的函数调整后:
void Widget::readyRead_Slot()
{
// ui->recvEdit->appendPlainText(tcpSocket->readAll()); // 显示不正常
// 读取数据
while (tcpSocket->bytesAvailable() > 0)
{
QByteArray inBlock;
// 设置数据大小为读取的数据大小
inBlock.resize(tcpSocket->bytesAvailable());
tcpSocket->read(inBlock.data(), inBlock.size());
readMsg = QString(inBlock); // readMsg为接收数据的字符串
// 显示接收到的数据
ui->recvEdit->appendPlainText(readMsg);
}
}
这时将正常显示
虽然是大致解决了问题,但是出现这个异常显示的原因还是没找到,但观察发现重新连接次数和空字符串行数,就像是每次断开连接都加了一个换行符给接收数据的缓存区;这个现象挺有趣,可能还是自己对TCP协议和编程理解的不够,所以不知道问题出在哪里,还是得花更多精力学习专研
第一次在这里提问,希望大家能替不才答疑Orz 感激不尽
回过头再检查了一下 大概理解原因了
根据Debugger和控制台输出检查得知问题和显示控件无关;通信过程中数据以流的方式传输,每当可读缓冲区有可读数据可用,有新的数据到来时,readyread信号发出Socket在接收到数据流时,会将数据存到一个QByteArray类型变量中,而输出时将字节数组进行字符串转换,第一次建立连接时服务器每次发出的数据能正常读出
再次连接时,因为只写了收发函数但没有对数据进行封装,这本来也是不严谨的。导致从缓冲区读取的数据大小和新数据大小不一致,这里面确实有滞留的控制符和其他不可见的码,读取的结果难以从调试信息和内存调用观察出来。需要再去看引用计时器和QTcpSocket基类QIODevice的接口定义等。而bytesAvailable判断了读取或处理的数据量,就切取了正常的部分
这次遇到问题里俺深刻认识到数据传输中对数据的合理处理和检验是必不可少的
你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答
本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。
因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。