[英]Writing to QTcpSocket does not always emit readyRead signal on opposite QTcpSocket
过去 5 天我一直被困在这个问题上,我不知道如何继续。
概述:
我有一个与data handler
库交互的client UI
, data handler
data handler
库利用network manager
库,这就是我的问题所在。
更多信息
首先,QT 为QTcpServer
(财富服务器)和QTcpSocket
(财富客户端)之间的交互提供了一个基本示例。
因此,我将这段代码实现到我自己的一个非常基本的示例中,它的作用就像一个魅力并且没有任何问题。
快速说明:
服务器应用程序运行,单击start server
,然后在客户端,在字段中输入文本并单击connect to server
并显示文本,简单!
问题:
将上面的代码实现到我的network manager
库中,不会在上面的服务器应用程序中触发QTcpSocket::readyRead()
。
它连接到server
,在那里QTcpServer::newConnection()
被触发,正如预期的那样,之后client
写入套接字,但服务器套接字上的readyRead()
不会触发,但是在给出的示例中。
注意:这个server-client
应用示例和我当前的应用使用相同的port
和ip address
,并且服务器也在运行。
更多信息:
从上面的代码,我直接从客户端复制过来的。 仅更改/修改了两件事:
这被复制到我的network mannager ::write()
方法中。 在运行我的应用程序时, QMainWindow
实例通过data handler
类传递并创建我的network manager
类的实例,该实例继承QObject
并实现Q_OBJECT
宏。
代码示例:
// client_UI
类(片段):
data_mananger *dman = new data_mananger(this); //this -> QMainWindow
ReturnObject r = dman->NET_AuthenticateUser_GetToken(Query);
// data_manager
库(代码段)
data_mananger::data_mananger(QObject *_parent) :
parent(_parent)
{}
ReturnObject data_mananger::NET_AuthenticateUser_GetToken(QString Query){
//Query like "AUTH;U=xyz@a;P=1234"
//convert query string to char
QByteArray ba = Query.toLatin1();
//send query and get QList return
ReturnCode rCode = networkManager.write(ba);
//...
}
// netman
库(片段)
//.h
class NETMANSHARED_EXPORT netman : public QObject
{
Q_OBJECT
public
netman();
netman(QObject *_parent);
//...
private:
QTcpSocket *tcp_con;
//...
};
//cpp
netman::netman(QObject *_parent) :
parent(_parent)
{
tcp_con = new QTcpSocket(parent);
}
return;
}
serverIP.setAddress(serverInfo.addresses().first().toIPv4Address());
}
ReturnCode netman::write(QByteArray message, int portNumber){
tcp_con->connectToHost(QHostAddress("127.0.0.1"), 5000);
if (!tcp_con->waitForConnected())
{
qDebug(log_lib_netman_err) << "Unable to connect to server";
return ReturnCode::FailedConnecting;
}
if (!tcp_con->isValid()) {
qDebug(log_lib_netman_err) << "tcp socket invalid";
return ReturnCode::SocketError;
}
if (!tcp_con->isOpen()) {
qDebug(log_lib_netman_err) << "tcp socket not open";
return ReturnCode::SocketError;
}
// QByteArray block(message);
QByteArray block;
QDataStream out(&block,QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << QString("Hello world");
if (!tcp_con->write(block)){
qDebug(log_lib_netman_err) << "Unable to send data to server";
return ReturnCode::WriteFailed;
}
else{
qDebug(log_lib_netman_info) << "Data block sent";
return ReturnCode::SentSuccess;
}
}
结论:
客户端的核心代码已经完全实现了,但是我看不出为什么会出现这个错误。
我非常感谢帮助/建议!
将tcp_con->flush()
语句添加到 write 函数的末尾。
您没有在接收器中收到readyRead
信号,因为写入的数据正在缓冲到套接字中,但实际上并未“通过线路”传输。 flush()
命令导致缓冲区被传输。 从文档
该函数尽可能多地从内部写缓冲区写入底层网络套接字,不阻塞。 如果有任何数据被写入,这个函数返回真; 否则返回 false。
在我的情况下,对串行端口和刷新有很多经验/挫折。 这相当于“你重启了吗?” 在套接字调试工具箱中。
如果其他一切正常,您可能不必flush
,但它是特定于应用程序的,取决于套接字的生命周期、TCP 窗口大小、套接字选项设置和各种其他因素。 也就是说,我总是刷新,因为我喜欢完全控制我的套接字,并且我想确保数据在我想要的时候被传输。 我不认为这是黑客攻击,但在某些情况下,它可能表明存在其他问题。 再次,特定于应用程序。
我很确定在财富服务器示例中不需要刷新,因为它们在sendFortune()
函数的末尾和Qt 文档中disconnectFromHost
了从sendFortune()
disconnectFromHost
:
尝试关闭套接字。 如果有待写入的数据等待写入,QAbstractSocket 将进入 ClosingState 并等待所有数据写入完毕。
如果套接字也被破坏,套接字也会断开连接,但是从我对您的代码的观察来看,您也没有这样做,并且缓冲区未满,因此实际上可能没有任何东西刺激缓冲区自行刷新。
其他原因可能是:
while(dataToTransmit)
),但实际上条件永远不会变为 false,这会导致事件循环被阻塞。QAbstractSocket::LowDelayOption
来禁用它,但它可能会对您的吞吐量产生不利影响......它通常用于延迟敏感的应用程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.