QUdpsocket首次发消息很慢的问题QTCpsocket应该也会

        公司客户端软件遇到一个问题,客户端在打开远程控制时候win7电脑会白屏一会,win10电脑正常,最终查到的原因是由于用到QUdpsocket 发送消息用到writeDatagram,第一次发送消息要很久才能返回。

        跟踪Qt源码

       qint64 QUdpSocket::writeDatagram(const char *data, qint64 size, const QHostAddress &address, quint16 port)
{
    Q_D(QUdpSocket);
#if defined QUDPSOCKET_DEBUG
    qDebug("QUdpSocket::writeDatagram(%p, %llu, \"%s\", %i)", data, size,
           address.toString().toLatin1().constData(), port);
#endif
    if (!d->doEnsureInitialized(QHostAddress::Any, 0, address))
        return -1;
    if (state() == UnconnectedState)
        bind();

    qint64 sent = d->socketEngine->writeDatagram(data, size, QIpPacketHeader(address, port));
    d->cachedSocketDescriptor = d->socketEngine->socketDescriptor();

    if (sent >= 0) {
        emit bytesWritten(sent);
    } else {
        d->setErrorAndEmit(d->socketEngine->error(), d->socketEngine->errorString());
    }
    return sent;
}

if (!d->doEnsureInitialized(QHostAddress::Any, 0, address))这个函数返回慢

然后继续往下跟,

bool QUdpSocketPrivate::doEnsureInitialized(const QHostAddress &bindAddress, quint16 bindPort,
                                            const QHostAddress &remoteAddress)
{
    const QHostAddress *address = &bindAddress;
    QAbstractSocket::NetworkLayerProtocol proto = address->protocol();
    if (proto == QUdpSocket::UnknownNetworkLayerProtocol) {
        address = &remoteAddress;
        proto = address->protocol();
    }

    // now check if the socket engine is initialized and to the right type
    if (!socketEngine || !socketEngine->isValid()) {
     
  resolveProxy(remoteAddress.toString(), bindPort);
        if (!initSocketLayer(address->protocol()))
            return false;
    }

    return true;
}

resolveProxy(remoteAddress.toString(), bindPort);这个函数返回慢

void QAbstractSocketPrivate::resolveProxy(const QString &hostname, quint16 port)
{
    QList<QNetworkProxy> proxies;

    if (proxy.type() != QNetworkProxy::DefaultProxy) {
        // a non-default proxy was set with setProxy
        proxies << proxy;
    } else {
        // try the application settings instead
        QNetworkProxyQuery query(hostname, port, QString(),
                                 socketType == QAbstractSocket::TcpSocket ?
                                 QNetworkProxyQuery::TcpSocket :
                                 QNetworkProxyQuery::UdpSocket);
        proxies = QNetworkProxyFactory::proxyForQuery(query);
    }

    // return the first that we can use
    for (const QNetworkProxy &p : qAsConst(proxies)) {
        if (socketType == QAbstractSocket::UdpSocket &&
            (p.capabilities() & QNetworkProxy::UdpTunnelingCapability) == 0)
            continue;

        if (socketType == QAbstractSocket::TcpSocket &&
            (p.capabilities() & QNetworkProxy::TunnelingCapability) == 0)
            continue;

        proxyInUse = p;
        return;
    }

    // no proxy found
    // DefaultProxy here will raise an error
    proxyInUse = QNetworkProxy();
}

内部有个判断,标红部分,是否采用网络代理,然后把网络代理关掉就正常了,关闭方法有两种,一种全局的

QNetworkProxyFactory::setUseSystemconfiguration(false);

一种单个的

m_webSocket.setProxy(QNetworkProxy::NoProxy);

设置之后就正常。

但是我们客户端以前版本就没问题,现在升级了qt版本,以前5.6.3升级到5.15.2

然后查了下资料,有人说是qt5.8之后默认采用QNetworkProxy::DefaultProxy,以前默认是QtNetworkProxy::NoProxy,参考以下链接

https://www.cnblogs.com/cppskill/p/11730452.html

但我查了下5.63,5.7的源码和5.15的源码对比了下

    inline QNetworkProxyPrivate(QNetworkProxy::ProxyType t = QNetworkProxy::DefaultProxy,
                                const QString &h = QString(), quint16 p = 0,
                                const QString &u = QString(), const QString &pw = QString())
        : hostName(h),
          user(u),
          password(pw),
          capabilities(defaultCapabilitiesForType(t)),
          port(p),
          type(t),
          capabilitiesSet(false)
    { }

都是一样默认DefaultProxy,所以虽然关闭网络代理可以解决这里还是有些疑惑,

这里记录下

这个问题就和webEngine加载web页面首次加载很慢的问题有点像,网上可以查到很多,也是因为开启了网络代理

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值