C++ (Qt)connect(mClients[clientNumber].data(), SIGNAL(disconnected()), this, SLOT(slotRejectClient()));
C++ (Qt)// Отключение клиентаint Server::slotRejectClient(){ int clientNumber = -1; // Поиск клиента, которого требуется отключить for (int i = 0; i < mMaxClients; i++) { if (mClients[i].data() != qobject_cast<QTcpSocket*>(sender())) continue; clientNumber = i; break; } if (clientNumber < 0) return -1; return this->disconnectClient(clientNumber);}
C++ (Qt)// Отключение и удаление клиентаint Server::disconnectClient(quint16 clientNumber){ disconnect(mClients[clientNumber].data(), SIGNAL(readyRead()), this, SLOT(slotReceiveData())); disconnect(mClients[clientNumber].data(), SIGNAL(disconnected()), this, SLOT(slotRejectClient())); disconnect(mClients[clientNumber].data(), SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotClientSocketError(QAbstractSocket::SocketError))); if (!mClients[clientNumber].isNull()) { // Сокет mClients[clientNumber].data()->close(); mClients[clientNumber].data()->deleteLater(); mClients[clientNumber] = 0; } emit signalSendTextToLog(QString("Клиент №%1 отключен!").arg(clientNumber)); return 0;}
C++ (Qt)0 QAbstractSocketPrivate::canReadNotification qabstractsocket.cpp 672 0x6cbc0172 1 QAbstractSocketPrivate::readNotification qabstractsocket_p.h 77 0x6cbff651 2 QAbstractSocketEngine::readNotification qabstractsocketengine.cpp 168 0x6cbb3855 3 QReadNotifier::event qnativesocketengine.cpp 1151 0x6cbcc009 4 QApplicationPrivate::notify_helper qapplication.cpp 4554 0xa8c020 5 QApplication::notify qapplication.cpp 3936 0xa89973 6 QCoreApplication::notifyInternal qcoreapplication.cpp 876 0x69dd3b76 7 QCoreApplication::sendEvent qcoreapplication.h 231 0x69e4488c 8 qt_internal_proc qeventdispatcher_win.cpp 484 0x69df92b7 9 USER32!IsWindowVisible C:\Windows\system32\user32.dll 0 0x76f3c4e7 10 QCharRef::operator= qstring.h 799 0x12112ca 11 USER32!IsWindowVisible C:\Windows\system32\user32.dll 0 0x76f3c5e7 12 qt_fast_timer_proc qeventdispatcher_win.cpp 428 0x69df90ec 13 USER32!IsWindowVisible C:\Windows\system32\user32.dll 0 0x76f3cc19 14 ?? 0
C++ (Qt)mClients[i].data() != qobject_cast<QTcpSocket*>(sender())
C++ (Qt)mClients[i].isNull() || mClients[i].data() != qobject_cast<QTcpSocket*>(sender())
C++ (Qt) // reset the read socket notifier state if we reentered inside the // readyRead() connected slot. if (readSocketNotifierStateSet && socketEngine && readSocketNotifierState != socketEngine->isReadNotificationEnabled()) { socketEngine->setReadNotificationEnabled(readSocketNotifierState); // Тут у нас socketEngine = @0xfeeefeee readSocketNotifierStateSet = false; }
C++ (Qt)QTimer::singleShot(1000, mClients[clientNumber].data(), SLOT(deleteLater()));
C++ (Qt)// Получение данных от клиента, обработкаint Server::slotReceiveData(){ bool result = false; int clientNumber = 0; // Поиск клиента, который выслал данных о MMF for (int i = 0; i < mMaxClients; i++) { if (mClients[i].data() != qobject_cast<QTcpSocket*>(sender())) continue; result = true; clientNumber = i; break; } if (!result) return -1; quint16 sizeOfPackage = 0; quint8 packageType = 0; QByteArray package; // Парсинг всех пришедших данных while (true) { // Считывание пришедших данных if (!mClients[clientNumber].isNull()) mReceivedData[clientNumber].append(mClients[clientNumber].data()->readAll()); // Проверка на условие: принято недостаточно данных if (mReceivedData[clientNumber].size() < (quint16)sizeof(quint16)) break; // Получение количества отправленных байт (0 - 1 байты) memcpy(&sizeOfPackage, mReceivedData[clientNumber].data(), sizeof(quint16)); // Проверка на условие: принят не весь пакет целиком if (mReceivedData[clientNumber].size() < sizeOfPackage || sizeOfPackage == 0) break; // Получение типа сообщения (2ой байт) memcpy(&packageType, mReceivedData[clientNumber].data() + sizeof(quint16), sizeof(quint8)); // Получение основной части пакета const int specialData = sizeof(quint16) + sizeof(quint8); package = mReceivedData[clientNumber].mid(specialData, sizeOfPackage - specialData); // Удаление распарсенных данных mReceivedData[clientNumber] = mReceivedData[clientNumber].mid(sizeOfPackage); // Обработка пакета switch (packageType) { case PackageType::Command: result = this->parseCommandPackage(clientNumber, package); break; case PackageType::RegInfo: result = this->parseRegInfoPackage(clientNumber, package); break; case PackageType::MMFName: result = this->parseMMFPackage(clientNumber, package); break; case PackageType::DescriptionRequest: break; case PackageType::CoefficientRequest: break; } if (!result) break; } if (!result) this->slotDisconnectClient(clientNumber); return 0;}
C++ (Qt)// Запись информации в журналint MainWindow::slotAddTextToLog(const QString text){ teLog->append(QDate::currentDate().toString("dd.MM.yyyy") + " " + QTime::currentTime().toString() + " - " + text); QCoreApplication::processEvents(); // Вот беда, судя по всему этот вызов обрабатывает не только UI-сообщения. Видимо в нем и была проблема return 0;}
C++ (Qt)QCoreApplication::processEvents();
QEventLoop::AllEvents - All events. Note that DeferredDelete events are processed specially. See QObject::deleteLater() for more details.QEventLoop::ExcludeUserInputEvents - Do not process user input events, such as ButtonPress and KeyPress. Note that the events are not discarded; they will be delivered the next time processEvents() is called without the ExcludeUserInputEvents flag.QEventLoop::ExcludeSocketNotifiers - Do not process socket notifier events. Note that the events are not discarded; they will be delivered the next time processEvents() is called without the ExcludeSocketNotifiers flag.