QTcpSocket在翻墙状态下失效的问题

在写TCP连接程序时,突然发现了这样的错误: socket error: The proxy type is invalid for this operation 发现是翻墙状态下进行了连接,翻回墙内之后正常了。这倒是挺有意思,值得研究一下。

先查了stackoverflow,发现是QNeworkProxy的问题,它的枚举ProxyType包含了几种类型,前四个是 DefaultProxy,Socks5Proxy,NoProxy,HttpProxy,,是不是问题在这里?在构造函数里定义了tcpSocket之后,加一行tcpSocket->setProxy(QNetworkProxy::NoProxy);。现在再到翻墙状态下测试,发现果然正常了。

这样还没完,要追本溯源研究问题。用sublime搜索文件夹F:\Qt5.10.1\5.10.1\Src\qtbase\src\network,找这个报错信息,最终发现调用路径是这样的:
先是QNativeSocketEngine::connectToHost

{
    ...
        if (!d->checkProxy(address))
        return false;
}

然后checkProxy函数

QNativeSocketEnginePrivate::checkProxy
{
    ......
    if (proxy.type() != QNetworkProxy::DefaultProxy &&
        proxy.type() != QNetworkProxy::NoProxy) {
        // QNativeSocketEngine doesn't do proxies
        setError(QAbstractSocket::UnsupportedSocketOperationError,
                 QNativeSocketEnginePrivate::InvalidProxyTypeString);
        return false;
    }
    ......
}

setError函数:

QNativeSocketEnginePrivate::setError
{
    ......
    case InvalidProxyTypeString:
        socketErrorString = QNativeSocketEngine::tr("The proxy type is invalid for this operation");
        break;
}

原来调用connectToHost时会先检查代理情况。那么我们试着检查socket的代理类型,用tcpSocket->proxy().type();分别在翻墙和不翻的状态下运行,结果居然都是0,也就是DefaultProxy,这怎么回事?这样到checkProxy应该不报错才对啊?

既然这样,那么就是这个函数用的不对,还看帮助吧,找啊找啊,终于找到这样一个函数[static] QNetworkProxy QNetworkProxy::applicationProxy(),看解释:
Returns the application level network proxying.
If a QAbstractSocket or QTcpSocket has the QNetworkProxy::DefaultProxy type, then the QNetworkProxy returned by this function is used.看来应该使用这个才对啊,再拿tcpSocket->proxy().applicationProxy().type();试验,这下就会发现未翻墙状态是NoProxy,翻墙状态是HttpProxy

这样一来就清楚了,但是注意上面的解释有一句:If a QAbstractSocket or QTcpSocket has the QNetworkProxy::DefaultProxy type。那么为什么socket默认用的是DefaultProxy而不是NoProxy?这是出于什么考虑?

接着用Google查,发现QTBUG网站和Qt开发者有一些讨论,一位开发者认为既然Chrome都用了系统代理,为什么我们不能?讨论的内容很多,不想都贴出来了,最后的结果是从Qt 5.8开始,socket默认代理类型是DefaultProxy

参考:QTBUG:”the proxy type is invalid for this operation”
Qt开发者的讨论:Should the system proxies default setting be switched to true?

猜你喜欢

转载自blog.csdn.net/yao5hed/article/details/81108521