当前位置:网站首页>QT socket setting connection timeout

QT socket setting connection timeout

2022-06-11 06:20:00 Kun Zai n

QT edition :5.15.0 msvc2019

QTcpSocket All operations are asynchronous by default ,connectToHost The connection also returns immediately , no return value , Whether the signal acquisition is successful , It's not a big problem either , But the default timeout 30s A little longer , There is no obvious other member function that can modify this timeout , These two methods are generally used to find them on the Internet :
1.  Use waitForConnected Change to synchronous mode and wait , Set the wait time , You can choose to cancel the connection in case of timeout , Generally, it needs to operate within the thread , Otherwise card UI
2.  Build one by yourself QTimer Timer , After timeout, check whether it is connected , If you are not connected, you can choose to cancel the connection 

 When looking at the source code, I found a third method :
 stay qabstractsocket.cpp Source file QAbstractSocketPrivate::_q_connectToNextAddress() Function ,
 Create a connection timeout timer , By default QNetworkConfigurationPrivate::DefaultTimeout(30000ms) Value as timeout , At the same time judge socket Of _q_networksession Whether the attribute exists , If it exists, get the timeout from the attribute ,_q_networksession The attribute is QSharedPointer<QNetworkSession> object 
void QAbstractSocketPrivate::_q_connectToNextAddress()
{
    ......

    if (!connectTimer) {
        connectTimer = new QTimer(q);
        QObject::connect(connectTimer, SIGNAL(timeout()),
                                    q, SLOT(_q_abortConnectionAttempt()),
                                    Qt::DirectConnection);
    }
    int connectTimeout = QNetworkConfigurationPrivate::DefaultTimeout;//  The default value is 30000ms
#ifndef QT_NO_BEARERMANAGEMENT // ### Qt6: Remove section
    QSharedPointer<QNetworkSession> networkSession = qvariant_cast< QSharedPointer<QNetworkSession> >(q->property("_q_networksession"));
    if (networkSession) {
        QNetworkConfiguration networkConfiguration = networkSession->configuration();
        connectTimeout = networkConfiguration.connectTimeout();
    }
#endif
    connectTimer->start(connectTimeout);

    ......
}
    

In fact, there is already a QTimer, Determine whether the connection timed out , Just set the timeout

In document QNetworkSession It is marked as abandoned , Not recommended , But I can't find any other way to set it , Just use it first , Set the timeout method as follows :

QNetworkConfigurationManager manager;
QNetworkConfiguration config = manager.defaultConfiguration();
config.setConnectTimeout(3000);
QSharedPointer<QNetworkSession> spNetworkSession(new QNetworkSession(config));
socket->setProperty("_q_networksession", QVariant::fromValue(spNetworkSession));

The reason why you need to set a short timeout , Because the project uses QModbusTcpClient Connect the lower computer , Connection timeouts often occur , Reconnection will be successful again , Need to shorten the timeout , To achieve the purpose of quickly connecting the upper and lower computers . The specific reason for the connection timeout has not been found yet . Use wireShark view message , Find out PC End send SYN After the handshake message , The next computer replied RST ACK, It has been like this many times in a row .

The solutions found on the Internet are not good

1. Qt By default IPv6 Connected , Read the intercepted message , It uses IPv4. You can also modify the connection parameters to add the specified IPv4 agreement connectToHost(strIP, port, QIODevice::ReadWrite, QAbstractSocket::IPv4Protocol);

2. It may be caused by agency problems , Then setting it to no proxy does not solve the problem

QNetworkProxyFactory::setUseSystemConfiguration(false);
socket->setProxy(QNetworkProxy::NoProxy);

3. Set up socket option, It may have some effect ( The effect is more likely to be after the connection is completed ), However, the connection timeout still occurs

socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
socket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);

There are also settings for sending and receiving buffer size

socket->setSocketOption(QAbstractSocket::SendBufferSizeSocketOption, 512);
socket->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption, 512);

原网站

版权声明
本文为[Kun Zai n]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206110605340806.html