gpt4 book ai didi

c++ - 如何使用 Qt 阻止 tcp 套接字?

转载 作者:搜寻专家 更新时间:2023-10-31 01:01:16 24 4
gpt4 key购买 nike

我使用QTcpSocket。我需要对套接字的任何写入/读取调用是同步的(阻塞)。

我知道有 waitForReadyRead()waitForBytesWritten(),但这两个方法在 Qt 文档中有标记,因为它们在 Windows 下可能会随机失败。我受不了了。

阻塞读取是最重要的(因为读取总是在向另一个对等点写入命令之后发生,所以我知道如果数据到达另一个对等点,它就会响应)。

我尝试了两种方法。

首先:

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 的值。

我知道实际上有数据要读取,因为它曾经使用第二种方法(但它有自己的问题)。

第二:

我有一种信号“拦截器”,它会阻塞当前上下文并处理事件循环,直到发出某个信号。这是“拦截器”:

信号等待.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();
};

信号等待.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 个字节或超时。

关于c++ - 如何使用 Qt 阻止 tcp 套接字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29451958/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com