Qt QTcpSocket never connects
Unsolved
Mobile and Embedded
-
I use a QTcpSocket to periodically receive data (every second roughly). It works great normally, but on iOS 13 Pro Max, if the user switches from wifi to cellular, the socket disconnects and will not reconnect if the socket is recreated. The socket needs to be recreated manually by the user at a later point. If they instead switch from cell to wifi, it works fine.
std::shared_ptr<NTRIPAPI::NTRIPReadState> NTRIPAPI::NTRIPConnection::NTRIPGet(NTRIPAPI::NTRIPRequest req) { auto readState = std::make_shared<NTRIPReadState>(); auto startTimer = new QTimer(this); auto connectTimer = new QTimer(this); QByteArray msg = req.ConstructRequest(m_settings); auto reconnect = [readState, req, connectTimer] { readState->in = NTRIPReadState::IN_START; // Time increases by square root to prevent overloading the NTRIP caster (no more than 5 minutes). connectTimer->setInterval(fmin(pow(connectTimer->interval()/1000.0, 2.0), 300.0)*1000.0); connectTimer->start(); }; auto addSocket = [=] { readState->socket = req.createSocket(); // return new QTcpSocket(); connect(readState->socket, &QAbstractSocket::connected, this, [readState, msg] { qsizetype size = msg.size(); qint64 cursor = 0; qint64 written; qDebug() << "Connected, writing request"; do { written = readState->socket->write(msg.mid(cursor)); cursor += written; } while (cursor < size && readState->socket->isWritable()); }); connect(readState->socket, &QAbstractSocket::readyRead, this, [] { // ... }); connect(readState->socket, &QAbstractSocket::disconnected, this, [this, readState, req, startTimer, connectTimer] { // ... }); connect(readState->socket, &QAbstractSocket::errorOccurred, this, [this, readState, req, startTimer, reconnect](QAbstractSocket::SocketError socketError) { bool isRecoverable = true; if (startTimer->isActive()) startTimer->stop(); // ... if (isRecoverable) { if (!readState->socket->isValid()) { readState->socket->deleteLater(); readState->socket = nullptr; } reconnect(); } else { readState->NTRIPDisconnect(); // socket->disconnectFromHost(); } }); }; // Setup the start timer. startTimer->setSingleShot(true); startTimer->setInterval(10000); // 10 s startTimer->callOnTimeout([this, readState, req, reconnect] { // Timeout occurred reconnect(); }); // Create the socket addSocket(); // Setup the connect timer to connect on the next frame connectTimer->setSingleShot(true); connectTimer->callOnTimeout([this, readState, startTimer, addSocket] { // todo: If the socket is invalid, delete it, recreate the socket if (readState->in == NTRIPReadState::IN_START) { if (readState->socket == nullptr) { qDebug() << "Recreating the socket"; addSocket(); } startTimer->start(); qDebug() << "Calling connectToHost"; readState->socket->connectToHost(m_settings->hostname(), m_settings->port()); } else qDebug() << "Ignoring connect request for invalid NTRIP GET request"; }); // Send the request connectTimer->start(0); connectTimer->setInterval(2000); return readState; }
This is a limited version of that connection code. Am I doing something wrong here? Or, is this an iOS bug (I believe Qt uses an NSStream) that I should report to Apple?
-
I would check the socket implementation for iOS to get started.