[英]How to make blocking tcp socket with Qt?
我使用QTcpSocket
。 我需要对套接字进行任何写/读调用以使其同步(阻塞)。
我知道有waitForReadyRead()
和waitForBytesWritten()
,但是Qt文档中标记了这两种方法,因为它们在Windows下可能会随机失败。 我不能为此。
阻塞读取是最重要的(因为读取总是在向另一个对等方写入命令之后进行的,所以我知道如果数据到达另一个对等方,它将回答)。
我尝试了2种方法。
第一:
QByteArray readBytes(qint64 count)
{
int sleepIterations = 0;
QByteArray resultBytes;
while (resultBytes.size() < count && sleepIterations < 100)
{
if (socket->bytesAvailable() == 0)
{
sleepIterations++;
QThread::msleep(100);
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
continue;
}
resultBytes += socket->read(qMin(count, socket->bytesAvailable()));
}
return resultBytes;
}
这应该等待字节可用于在套接字上读取,同时处理事件循环,因此套接字正在做必要的内部工作。
不幸的是-出于我未知的原因bytesAvailable()
有时返回正确的字节数,但有时却永远不会返回大于0的任何值。
我实际上知道要读取数据,因为它曾经与第二种方法一起工作(但它有其自身的问题)。
第二:
我有一种信号“阻止程序”,它阻止当前上下文并处理事件循环,直到发出某些信号为止。 这是“阻止者”:
SignalWait.h:
class SignalWait : public QObject
{
Q_OBJECT
public:
SignalWait(QObject *object, const char *signal);
bool wait(int msTimeout);
private:
bool called = false;
private slots:
void handleSignal();
};
SignalWait.cpp:
SignalWait::SignalWait(QObject* object, const char* signal) :
QObject()
{
connect(object, signal, this, SLOT(handleSignal()));
}
bool SignalWait::wait(int msTimeout)
{
QTime timer(0, 0, 0, msTimeout);
timer.start();
while (!called && timer.elapsed() < msTimeout)
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
return called;
}
void SignalWait::handleSignal()
{
called = true;
}
然后我像这样使用它:
SignalWait signalWait(socket, SIGNAL(readyRead()));
// ...
// socket->write(...);
// ...
if (!signalWait.wait(30000))
{
// error
return;
}
bytes = socket->read(size);
这种方法似乎效果更好,但有时也会失败。 我不知道为什么 就像readyRead()
信号从未发出过, SignalWait
一直等待直到超时。
我没主意了。 处理它的正确方法是什么?
我建议使用异步方法,但是如果您真的想使用同步方法,那么更好的方法是使用本地事件循环:
QTimer timer;
timer.setSingleShot(true);
QEventLoop loop;
loop.connect(socket, SIGNAL(readyRead()), SLOT(quit()));
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
while (resultBytes.size() < count)
{
timer.start(msTimeout);
loop.exec();
if(timer.isActive())
resultBytes += socket->read(qMin(count, socket->bytesAvailable()));
else
break;
}
在这里,它等待直到读取count
字节或达到超时为止。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.