标签: qtcpsocket

如何确保来自QTcpSocket的readyRead()信号不能错过?

QTcpSocket用于接收数据时,使用的readyRead()信号表示新数据可用.但是,当您在相应的插槽实现中读取数据时,不会readyRead()发出其他内容.这可能是有意义的,因为您已经在函数中,您正在读取所有可用的数据.

问题描述

但是假设此插槽的以下实现:

void readSocketData()
{
    datacounter += socket->readAll().length();
    qDebug() << datacounter;
}
Run Code Online (Sandbox Code Playgroud)

如果一些数据在通话后readAll()但在离开插槽之前到达怎么办?如果这是另一个应用程序发送的最后一个数据包(或者至少是最后一个数据包),该怎么办?不会发出额外的信号,因此您必须确保自己读取所有数据.

一种最小化问题的方法(但不能完全避免)

当然我们可以像这样修改插槽:

void readSocketData()
{
    while(socket->bytesAvailable())
        datacounter += socket->readAll().length();
    qDebug() << datacounter;
}
Run Code Online (Sandbox Code Playgroud)

但是,我们还没有解决问题.数据仍然可能在socket->bytesAvailable()-check 之后到达(甚至在函数的绝对末尾放置/另一个检查也无法解决此问题).

确保能够重现问题

由于这个问题当然很少发生,我坚持第一个插槽的实现,我甚至会添加一个人工超时,以确保出现问题:

void readSocketData()
{
    datacounter += socket->readAll().length();
    qDebug() << datacounter;

    // wait, to make sure that some data arrived
    QEventLoop loop;
    QTimer::singleShot(1000, &loop, SLOT(quit()));
    loop.exec();
}
Run Code Online (Sandbox Code Playgroud)

然后我让另一个应用程序发送100,000字节的数据.这是发生的事情:

新的联系!
32768(或16K或48K)

读取消息的第一部分,但不再读取结尾,因为readyRead()不会再次调用.

我的问题是:什么是最好的方法来确定,这个问题永远不会发生?

可能解决方案

我提出的一个解决方案是再次在末尾再次调用相同的插槽,并在插槽的开头检查是否还有更多数据要读取:

void readSocketData(bool selfCall) // default …
Run Code Online (Sandbox Code Playgroud)

c++ qt qtcpsocket

28
推荐指数
2
解决办法
2万
查看次数

QTcpSocket状态始终连接,甚至拔掉以太网线

我有一个QTcpSocket,我正在读一个循环.每次读取完整数据包或出现错误时,我都会手动检查循环内套接字的状态:

    while(true){
    if(socket->state()==QAbstractSocket::ConnectedState){
        qDebug()<<"Socket status: connected. Looking for packets...";
        if(socket->waitForReadyRead(2000)){
        //...
    }
Run Code Online (Sandbox Code Playgroud)

当我执行de program时,一旦连接并且循环开始,它总是打印qDebug()<<"Socket status: connected. Looking for packets..."; 然后停留,waitForReadyRead直到一些数据准备好被读取.

问题是没有检测到断开连接.如果我断开网络与操作系统选项的连接,或者即使我拔掉以太网线,它的行为也是一样的:套接字状态等于QAbstractSocket::ConnectedState,所以它会继续,但当然没有收到任何东西.

我还试图检测连接disconnected()信号(在第一次连接后)到重新连接功能的断开连接:

// Detect disconnection in order to reconnect
    connect(socket, SIGNAL(disconnected()), this, SLOT(reconnect()));

void MyClass::reconnect(){
    qDebug()<<"Signal DISCONNECTED emitted. Now trying to reconnect";
    panelGUI->mostrarValueOffline();
    socket->close();
    prepareSocket((Global::directionIPSerialServer).toLocal8Bit().data(), 8008, socket);
    qDebug()<<"Reconnected? Status: "<<socket->state();
}
Run Code Online (Sandbox Code Playgroud)

但是信号永远不会被发出,因为这段代码永远不会被执行.这是合乎逻辑的,因为看起来套接字状态总是如此ConnectedState.

如果我再次插入,连接将恢复并再次开始接收数据,但我确实想检测断开连接以在GUI上显示"已断开连接".

为什么QTcpSocket会以这种方式运行,我该如何解决这个问题呢?

编辑:我在类构造函数中创建套接字,然后初始化调用prepareSocket函数:

socket = new QTcpSocket();
socket->moveToThread(this);

bool prepareSocket(QString address, int port, QTcpSocket *socket) {
    socket->connectToHost(address, port); …
Run Code Online (Sandbox Code Playgroud)

c++ qt state network-programming qtcpsocket

25
推荐指数
2
解决办法
2万
查看次数

如何找到Qt的版本?

我怎么知道我使用的是哪个版本的Qt?当我打开Qt Creator时,它显示"欢迎来到Qt Creator 2.3".但是,在构建设置中,它显示Qt Version 4.7.1.

qt4 pyqt qt-creator qtcpsocket qtcore

24
推荐指数
6
解决办法
5万
查看次数

QTcpSocket :: waitForBytesWritten的行为?

我对QTcpSocket::waitForBytesWritten()...... 的行为有点困惑

直到这个功能什么时候阻止?

  • 在将数据写入OS的内部缓冲区以通过TCP传输之前?
  • 直到数据物理转换为TCP数据包并发送?
  • 在传输整个数据并且远程客户端确认已收到所有数据包之前?

我查看了文档,但似乎并不十分清楚.

qt tcp transmission qtcpsocket

10
推荐指数
1
解决办法
5144
查看次数

使用QDataStream从QTcpSocket读取

我需要通过一个发送二进制数据QTcpSocket.我正在考虑使用QDataStream,但是我遇到了一个问题 - 如果在我尝试阅读的时候没有数据到达,它会无声地失败.

例如,如果我有这个代码:

QString str;
stream >> str;
Run Code Online (Sandbox Code Playgroud)

如果套接字中当前没有数据,它将无提示失败.有没有办法告诉它阻止?

c++ qt qtcpsocket

8
推荐指数
2
解决办法
2万
查看次数

QSslSocket:无法解析SSLV2_client_method

我在debian wheezy的Qt 5.4.1中使用QSslSocket创建了一个sslclient和sslserver.当我运行程序时,他们根本不工作.在调试我的代码后,我看到它在尝试从中创建一个新对象时,在约束器中QSslSocket返回此错误(cannot resolve SSLV2_client_method).

这是我的代码块:

SSlClient::SSlClient(QObject *parent) : QObject(parent)
{
    client = new QSslSocket(this);
    client->setProtocol(QSsl::SslV3);

    connect(client, SIGNAL(encrypted()), this, SLOT(startTransfer()));
    connect(client, SIGNAL(encryptedBytesWritten(qint64)), this, SLOT(byteWritten()));


}
Run Code Online (Sandbox Code Playgroud)

qt client-server qtcpsocket qtcpserver qsslsocket

7
推荐指数
1
解决办法
7126
查看次数

C++ Qt - QTcpSocket - 找不到文件

我正在使用QtQTcpSocket创建一个小型聊天客户端/服务器应用程序.

编译代码时,编译器返回以下错误:

main.cpp:3:22: fatal error: QTcpSocket: No such file or directory
Run Code Online (Sandbox Code Playgroud)

这指的是#include <QTcpSocket>.

该库位于何处,如何安装?

c++ qt qtcpsocket

6
推荐指数
1
解决办法
1万
查看次数

将现有的QTcpSocket变为QSslSocket

是否可以创建一个新的QSslSocket并使其获得现有TCP连接的所有权,并且旧的QTcpSocket将被丢弃,而不会中断或关闭TCP连接?

我需要这个在我的FTP服务器中实现显式FTPS,这要求最初连接是未加密的,并且只有在FTP客户端的请求(命令AUTH SSLAUTH TLS)时,如果它发生,则启动SSL/TLS握手.

c++ qt qtcpsocket qsslsocket

6
推荐指数
1
解决办法
1301
查看次数

如何在QTcpSocket中读取完整数据?

现在服务器(用java实现)会向我发送一些流数据,我的代码如下:

connect(socket, SIGNAL(readyRead()), this, SLOT(read_from_server()));
Run Code Online (Sandbox Code Playgroud)

read_from_server():

{
    while (socket->bytesAvailable())
    {
        QString temp = socket->readAll();
    }
}
Run Code Online (Sandbox Code Playgroud)

但我发现即使服务器发给我一个只有几个字符的字符串,数据被截断,我的函数被调用两次,因此temp是我想要的永不完整的数据.
如果服务器发给我一个更长的字符串,我的函数可能会被调用三次或更多次,这使得我很难知道数据完全被传输的时间.
所以任何人都可以告诉我如何轻松完全接收数据,没有这么多困扰的步骤?如果这与其他一些问题重复,我很抱歉,我无法让他们的答案适合我.非常感谢!

c++ qt qtcpsocket qt5

6
推荐指数
1
解决办法
2万
查看次数

对于频繁的请求,保持套接字打开更好,还是每次都关闭套接字更好

我正在编写一个程序,每秒向服务器发出 1 个 GET 请求。我正在使用套接字(QTcpSocket),我想知道是否应该在请求中包含“连接:关闭”,然后为每个请求重新创建套接字,或者是否最好简单地保持套接字处于活动状态,因为我正在重复每秒一次相同的请求。

c++ sockets qtcpsocket

6
推荐指数
2
解决办法
3293
查看次数