场景
客户端使用QTcpSocket在子线程中与服务端进行一问一答的通信,QTcpSocket的读写在子线程中进行,发送数据后,服务端已有回应,但一直收不到。
代码模版如下:
//子线程
void Thread::run() {
bool rwFlag = true;
while (1) {
if (rwFlag) {
if (hasData()) { //有数据时发送
send();
}
} else {
recv(); //接收
}
rwFlag = !rwFlag;
msleep(10);
}
}
解决方法
方法一
在发送之后添加waitForReadReady,等待服务端回应,修改代码模版如下:
//子线程
void Thread::run() {
while (1) {
if (hasData() &&
send() &&
waitForReadReady()) { //发送消息并等待回应
recv();
}
msleep(10);
}
}
waitForReadReady默认等待时间为30000毫秒,可以按需求调整参数。
等待过程中,只要服务端发送了数据,客户端就能监测到。但超时之后服务端仍然没有发送数据,同样会收不到数据。
方法二
如果实际应用场景中存在服务端过很久才会回复的情况,可以添加心跳机制(每隔一段时间发送一条消息,以检测连接状态),如下。
//子线程
void Thread::run() {
bool rwFlag = true;
int heartBeatCounter = 0;
while (1) {
if (rwFlag) {
if (hasData() &&
send() &&
waitForReadReady(100)) { //发送消息并等待回应
recv();
}
} else {
recv(); //接收
}
rwFlag = !rwFlag;
msleep(10);
heartBeatCounter++;
if (heartBeatCounter == 100) {
addheartBeatData(); //添加心跳消息
heartBeatCounter = 0;
}
}
}
因为tcp的读写并不是实时的,有可能服务端写入了,但客户端一直没有拉取数据,结果一直收不到数据。
添加心跳检测后,服务端发送的数据可以通过心跳检测来推送,解决了客户端一直无法收到回复的问题。