为什么我的代码无法读取QTcpSocket上可用的字节数?有想法吗? [英] Why can't my code read the number of bytes available on a QTcpSocket? Ideas?

查看:438
本文介绍了为什么我的代码无法读取QTcpSocket上可用的字节数?有想法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在循环主体中,我有以下代码片段,负责从QTcpSocket中读取数据(nntp是指向QTcpSocket的指针).

std::vector<char> buffer;
int bytesAvailable = nntp->bytesAvailable();
qDebug() << "bytesAvailable: "<<bytesAvailable;
if(bytesAvailable <= 0) break;
buffer.resize(bytesAvailable);
bytesRead = nntp->read(&buffer[0], bytesAvailable);
qDebug() << (nntp->state() == QAbstractSocket::ConnectedState);
qDebug() << "bytesRead: "<<bytesRead;

间歇性地,这输出类似于以下内容:

bytesAvailable:  24 
true 
bytesRead:  0 

我那里的代码行为不当.这对我来说似乎很奇怪,表明我完全误解了QTcpSockets的工作方式.当然,如果bytesAvailable> 0,则随后的读取将意味着可以将bytesAvailable字节读入缓冲区,在这种情况下,bytesRead应该== bytesAvailable.还是我错过了什么?我目前的怀疑是这可能是某种形式的内存损坏.

抛出一些nntp.errorString()消息报告在此失败期间,网络操作超时".我需要调查这意味着...(想法?)

似乎网络操作超时"仅表示读取超时.当代码正常工作时(即间歇性地),我仍然会遇到此错误".

可以在此pastebin链接中找到上述代码段的完整算法上下文./p>

EDIT 4:此功能与EDIT 3中的版本稍有不同,但仍然存在相同的问题,位于此较新的pastebin链接

解决方案

我发现了问题:我一直试图读取的QTcpSocket属于另一个线程.即使根据QIODevice的缓冲区可用的字节,也因此无法读取.

因此:

*始终确保要读取的套接字属于您要在其上进行读取的线程*

为解决此问题,正如泰勒在上面建议的那样,可以利用QTcpSocket的信号和插槽基础结构(首选).它具有适当的线程基础结构,从理论上讲应该使事情简单得多.

OR

要超级谨慎

(a)利用自己的QThread,将包含QTcpSocket的对象移动到此QThread

然后

(b)在另一个线程的阻塞读取循环中使用QTcpSocket的waitForReadyRead.

后一种方法比较困难,因为如果要在以后的读写中为其他线程保留QTcpSocket,则在将其移到另一个线程并由另一个线程处理之后,必须将其移回主线程.螺纹,然后再移动另一个螺纹. -让我很头疼,只是想说些什么!当然,人们可能会选择在整个过程中保持相同的QTcpSocket工作线程,以便仅需移动一次,或者每次需要QTcpSocket时简单地创建一个新的QTcpSocket,将其移动到自己的QThread,然后在完成时立即将其删除

如果可以的话,基本上请采用第一种信号和插槽方法.

I have the following snippet of code in the body of a loop responsible for reading data from a QTcpSocket (nntp is a pointer to a QTcpSocket).

std::vector<char> buffer;
int bytesAvailable = nntp->bytesAvailable();
qDebug() << "bytesAvailable: "<<bytesAvailable;
if(bytesAvailable <= 0) break;
buffer.resize(bytesAvailable);
bytesRead = nntp->read(&buffer[0], bytesAvailable);
qDebug() << (nntp->state() == QAbstractSocket::ConnectedState);
qDebug() << "bytesRead: "<<bytesRead;

Intermittently, this outputs something akin to the following:

bytesAvailable:  24 
true 
bytesRead:  0 

And my code from there mis-behaves. This seems very strange to me and suggests that I completely misunderstand how QTcpSockets work. Surely if bytesAvailable > 0 then a subsequent read will mean that bytesAvailable bytes can be read into a buffer in which case bytesRead should == bytesAvailable. Or am I missing something? My current suspicion is that it could be a memory corruption of some sort..

EDIT: Throwing in some nntp.errorString() messages reports that during this failure, the "Network operation timed out". I need to investigate what this means...(ideas?)

EDIT 2: It seems that "Network operation timed out" just means that the read timed out. When the code works as it should (i.e. intermittently), I still get this 'error'.

EDIT 3: The full algorithmic context for the above snippet of code can be found at this pastebin link.

EDIT 4: A slightly different version of the function in EDIT 3 but still with the same problems nonetheless is at this newer pastebin link

解决方案

I discovered the issue: the QTcpSocket I had been trying to read from belonged to a different thread. Even though bytes were available according to the QIODevice's buffer, they could not be read because of this.

Therefore:

* Always ensure that the socket you want to read from belongs to the thread on which you want to do the reading *

To help with this, and as Taylor suggested above, one can take advantage of QTcpSocket's signals and slots infrastructure (preferred). This has the appropriate threading infrastructure in place and in theory should make things a lot simpler.

OR

Be super-cautious and

(a) utilize ones own QThread, moving the object that contains the QTcpSocket to this QThread

then,

(b) use the waitForReadyRead of the QTcpSocket in the blocking read loop of this other thread.

This latter approach is more difficult since if one wants to retain the QTcpSocket for other threads in future reads and writes, then after it has been moved to another thread and processed by that other thread, it must be moved back to the main thread before it can ever be moved a further thread. -- gives me a headache just trying to word that! Of course one might chose to keep the same QTcpSocket worker thread throughout so that it only has to be moved once, or simple creating a new QTcpSocket each time a QTcpSocket is required, moving it to its own QThread and then immediately deleting it when its finished with.

Basically, go for the first signals and slots method if you can.

这篇关于为什么我的代码无法读取QTcpSocket上可用的字节数?有想法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆