void Server::disconnected() { QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender()); sockets.removeAll(socket); socket->deleteLater(); }
void ServerPanelRpcServer::DiscardClient() { // Open the socket QTcpSocket* cSocket = (QTcpSocket*) sender(); // Schedule the socket for deletion cSocket->deleteLater(); }
/*! \internal */ void QWebSocketServerPrivate::handshakeReceived() { if (Q_UNLIKELY(!currentSender)) { qWarning() << QWebSocketServer::tr("Sender is NULL. This is a Qt bug."); return; } QTcpSocket *pTcpSocket = qobject_cast<QTcpSocket*>(currentSender->sender); if (Q_UNLIKELY(!pTcpSocket)) { qWarning() << QWebSocketServer::tr("Sender is not a QTcpSocket. This is a Qt bug!!!"); return; } //When using Google Chrome the handshake in received in two parts. //Therefore, the readyRead signal is emitted twice. //This is a guard against the BEAST attack. //See: https://www.imperialviolet.org/2012/01/15/beastfollowup.html //For Safari, the handshake is delivered at once //FIXME: For FireFox, the readyRead signal is never emitted //This is a bug in FireFox (see https://bugzilla.mozilla.org/show_bug.cgi?id=594502) if (!pTcpSocket->canReadLine()) { return; } disconnect(pTcpSocket, &QTcpSocket::readyRead, this, &QWebSocketServerPrivate::handshakeReceived); Q_Q(QWebSocketServer); bool success = false; bool isSecure = false; if (m_pendingConnections.length() >= maxPendingConnections()) { pTcpSocket->close(); pTcpSocket->deleteLater(); qWarning() << QWebSocketServer::tr("Too many pending connections: " \ "New WebSocket connection not accepted."); setError(QWebSocketProtocol::CloseCodeAbnormalDisconnection, QWebSocketServer::tr("Too many pending connections.")); return; } QWebSocketHandshakeRequest request(pTcpSocket->peerPort(), isSecure); QTextStream textStream(pTcpSocket); request.readHandshake(textStream); if (request.isValid()) { QWebSocketCorsAuthenticator corsAuthenticator(request.origin()); Q_EMIT q->originAuthenticationRequired(&corsAuthenticator); QWebSocketHandshakeResponse response(request, m_serverName, corsAuthenticator.allowed(), supportedVersions(), supportedProtocols(), supportedExtensions()); if (response.isValid()) { QTextStream httpStream(pTcpSocket); httpStream << response; httpStream.flush(); if (response.canUpgrade()) { QWebSocket *pWebSocket = QWebSocketPrivate::upgradeFrom(pTcpSocket, request, response); if (pWebSocket) { addPendingConnection(pWebSocket); Q_EMIT q->newConnection(); success = true; } else { setError(QWebSocketProtocol::CloseCodeAbnormalDisconnection, QWebSocketServer::tr("Upgrade to WebSocket failed.")); } } else { setError(response.error(), response.errorString()); } } else { setError(QWebSocketProtocol::CloseCodeProtocolError, QWebSocketServer::tr("Invalid response received.")); } } if (!success) { qWarning() << QWebSocketServer::tr("Closing socket because of invalid or unsupported request."); pTcpSocket->close(); } }
void Tunnelc::promiseChannelCleanup(ToxTunChannel *chan) { qDebug()<<chan<<sender(); QObject *snderobj = (QObject*)sender(); QTimer *repeat_timer = NULL; qDebug()<<snderobj->objectName()<<snderobj->metaObject()->className(); if (chan == NULL) { repeat_timer = (QTimer*)snderobj; assert(repeat_timer != NULL); int conid = repeat_timer->property("conid").toInt(); if (!m_conid_chans.contains(conid)) { qDebug()<<"maybe too late repeat check self sock close timer event"; repeat_timer->deleteLater(); return; } chan = m_conid_chans[conid]; assert(chan != NULL); } else { // snderobj is ENetPoll or QTcpSocket } QTcpSocket *sock = chan->m_sock; ENetPeer *enpeer = chan->m_enpeer; //////////// QHash<QString, bool> promise_results; promise_results["sock_closed"] = chan->sock_closed; // promise_results["enet_closed"] = chan->enet_closed; promise_results["peer_sock_closed"] = chan->peer_sock_closed; bool promise_result = true; for (auto it = promise_results.begin(); it != promise_results.end(); it ++) { QString key = it.key(); bool val = it.value(); promise_result = promise_result && val; } if (true) { // 检测对方最近的回包情况 if (!promise_result && repeat_timer == NULL && promise_results["peer_sock_closed"] && !promise_results["sock_closed"]) { qDebug()<<"here"; if (chan->last_recv_peer_pkt_time == QDateTime()) { qDebug()<<"maybe can close socket right now, because recv nothing forever"; } QTimer *t = new QTimer(); t->setInterval(500); t->setSingleShot(true); t->setProperty("conid", QVariant(chan->m_conid)); // // QObject::connect(t, &QTimer::timeout, this, &Tunneld::promiseChannelCleanup, Qt::QueuedConnection); QObject::connect(t, SIGNAL(timeout()), this, SLOT(promiseChannelCleanup()), Qt::QueuedConnection); qDebug()<<"start repeat check sock close timer:"; t->start(); } if (!promise_result && repeat_timer != NULL && promise_results["peer_sock_closed"] && !promise_results["sock_closed"]) { // QDateTime now_time = QDateTime::currentDateTime(); uint32_t last_recv_to_now_time = chan->last_recv_peer_pkt_time.msecsTo(now_time); qDebug()<<"here:"<<last_recv_to_now_time<<enpeer->lastReceiveTime; if (last_recv_to_now_time > 7000) { qDebug()<<"last recv to now, force close self socket:"<<last_recv_to_now_time <<enpeer->incomingPeerID<<enpeer->outgoingPeerID; // 不能直接关闭,要在当前函数执行完后,即下一次事件的时候开始执行。 QTimer::singleShot(1, sock, &QTcpSocket::close); // QTimer *t = new QTimer(); // t->setSingleShot(true); // QObject::connect(t, &QTimer::timeout, sock, &QTcpSocket::close, Qt::QueuedConnection); // t->start(1); repeat_timer->deleteLater(); } else { repeat_timer->start(); } } } if (!promise_result) { qDebug()<<"promise nooooot satisfied:"<<promise_results<<chan->m_conid; return; } chan->promise_close_time = QDateTime::currentDateTime(); qDebug()<<"promise satisfied."<<chan->m_conid; ///// do cleanup bool force_closed = chan->force_closed; // enpeer->toxchan = NULL; // cleanup peerRemoveChan(enpeer, chan); this->m_sock_chans.remove(sock); // this->m_enpeer_chans.remove(enpeer); this->m_conid_chans.remove(chan->m_conid); delete chan; sock->disconnect(); sock->deleteLater(); if (repeat_timer != NULL) repeat_timer->deleteLater(); qDebug()<<"curr chan size:"<<this->m_sock_chans.count()<<this->m_conid_chans.count(); if (force_closed) { return; } // 延时关闭enet_peer auto later_close_timeout = [enpeer]() { qDebug()<<enpeer<<enpeer->state; if (enpeer->state != ENET_PEER_STATE_CONNECTED) { qDebug()<<"warning, peer currently not connected:"<<enpeer->incomingPeerID; } if (! (enet_list_empty (& enpeer -> outgoingReliableCommands) && enet_list_empty (& enpeer -> outgoingUnreliableCommands) && enet_list_empty (& enpeer -> sentReliableCommands))) { qDebug()<<"warning, maybe has unsent packet:"<<enpeer->incomingPeerID; // 这也有可能是ping包啊,真是不好处理 } qDebug()<<"last recv time:"<<enpeer->incomingPeerID <<enetx_time_diff(enpeer->lastReceiveTime, enet_time_get()); qDebug()<<"restore peer timeout, ping interval"; enet_peer_timeout(enpeer, ENET_PEER_TIMEOUT_LIMIT*2, ENET_PEER_TIMEOUT_MINIMUM*2, ENET_PEER_TIMEOUT_MAXIMUM*2); enet_peer_ping_interval(enpeer, ENET_PEER_PING_INTERVAL*2); // enet_peer_disconnect_now(enpeer, qrand()); enet_peer_disconnect_later(enpeer, qrand()); }; qDebug()<<"last recv time:"<<enpeer->incomingPeerID <<enetx_time_diff(enpeer->lastReceiveTime, enet_time_get()); QTimer::singleShot(5678, later_close_timeout); }
void HttpSocket::readClient() { if (terminated) { return; } QTcpSocket *socket = static_cast<QTcpSocket *>(sender()); if (!socket) { return; } if (socket->bytesAvailable() >= constMaxBuffer) { // Request too large, reject sendErrorResponse(socket, 400); socket->close(); DBUG << "Request too large"; return; } if (socket->canReadLine()) { QList<QByteArray> tokens = split(socket->readLine()); // QRegExp("[ \r\n][ \r\n]*")); if (tokens.length()>=2 && "GET"==tokens[0]) { QStringList params = QString(socket->readAll()).split(QRegExp("[\r\n][\r\n]*")); DBUG << "params" << params << "tokens" << tokens; QUrl url(QUrl::fromEncoded(tokens[1])); QUrlQuery q(url); bool ok=false; qint32 readBytesFrom=0; qint32 readBytesTo=0; getRange(params, readBytesFrom, readBytesTo); DBUG << "readBytesFrom" << readBytesFrom << "readBytesTo" << readBytesTo; if (q.hasQueryItem("cantata")) { Song song=HttpServer::self()->decodeUrl(url); if (!isCantataStream(song.file)) { sendErrorResponse(socket, 400); socket->close(); DBUG << "Not cantata stream file"; return; } if (song.isCdda()) { #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND QStringList parts=song.file.split("/", QString::SkipEmptyParts); if (parts.length()>=3) { QString dev=QLatin1Char('/')+parts.at(1)+QLatin1Char('/')+parts.at(2); CdParanoia cdparanoia(dev, false, false, true, Settings::self()->paranoiaOffset()); if (cdparanoia) { int firstSector = cdparanoia.firstSectorOfTrack(song.id); int lastSector = cdparanoia.lastSectorOfTrack(song.id); qint32 totalSize = ((lastSector-firstSector)+1)*CD_FRAMESIZE_RAW; int count = 0; bool writeHeader=0==readBytesFrom; // Only write header if we are not seeking... // int bytesToDiscard = 0; // Number of bytes to discard in first read sector due to range request in HTTP header // if (readBytesFrom>=ExtractJob::constWavHeaderSize) { // readBytesFrom-=ExtractJob::constWavHeaderSize; // } // if (readBytesFrom>0) { // int sectorsToSeek=readBytesFrom/CD_FRAMESIZE_RAW; // firstSector+=sectorsToSeek; // bytesToDiscard=readBytesFrom-(sectorsToSeek*CD_FRAMESIZE_RAW); // } cdparanoia.seek(firstSector, SEEK_SET); ok=true; writeMimeType(QLatin1String("audio/x-wav"), socket, readBytesFrom, totalSize+ExtractJob::constWavHeaderSize, false); if (writeHeader) { ExtractJob::writeWavHeader(*socket, totalSize); } bool stop=false; while (!terminated && (firstSector+count) <= lastSector && !stop) { qint16 *buf = cdparanoia.read(); if (!buf) { break; } char *buffer=(char *)buf; qint32 writePos=0; qint32 toWrite=CD_FRAMESIZE_RAW; // if (bytesToDiscard>0) { // int toSkip=qMin(toWrite, bytesToDiscard); // writePos=toSkip; // toWrite-=toSkip; // bytesToDiscard-=toSkip; // } if (toWrite>0 && !write(socket, &buffer[writePos], toWrite, stop)) { break; } count++; } } } #endif } else if (!song.file.isEmpty()) { #ifdef Q_OS_WIN if (tokens[1].startsWith("//") && !song.file.startsWith(QLatin1String("//")) && !QFile::exists(song.file)) { QString share=QLatin1String("//")+url.host()+song.file; if (QFile::exists(share)) { song.file=share; DBUG << "fixed share-path" << song.file; } } #endif QFile f(song.file); if (f.open(QIODevice::ReadOnly)) { qint32 totalBytes = f.size(); writeMimeType(detectMimeType(song.file), socket, readBytesFrom, totalBytes, true); ok=true; qint32 readPos = 0; qint32 bytesRead = 0; if (0!=readBytesFrom) { if (!f.seek(readBytesFrom)) { ok=false; } bytesRead+=readBytesFrom; } if (0!=readBytesTo && readBytesTo>readBytesFrom && readBytesTo!=totalBytes) { totalBytes-=(totalBytes-readBytesTo); } if (ok) { static const int constChunkSize=32768; char buffer[constChunkSize]; bool stop=false; do { bytesRead = f.read(buffer, constChunkSize); readPos+=bytesRead; if (!write(socket, buffer, bytesRead, stop) || f.atEnd()) { break; } } while (readPos<totalBytes && !stop && !terminated); } } else { DBUG << "Failed to open" << song.file; } } } if (!ok) { sendErrorResponse(socket, 404); } socket->close(); if (QTcpSocket::UnconnectedState==socket->state()) { socket->deleteLater(); } } else { // Bad Request sendErrorResponse(socket, 400); socket->close(); DBUG << "Bad Request"; return; } } }
/*! \internal */ void QWebSocketPrivate::open(const QUrl &url, bool mask) { //just delete the old socket for the moment; //later, we can add more 'intelligent' handling by looking at the URL //m_pSocket.reset(); Q_Q(QWebSocket); if (!url.isValid() || url.toString().contains(QStringLiteral("\r\n"))) { setErrorString(QWebSocket::tr("Invalid URL.")); Q_EMIT q->error(QAbstractSocket::ConnectionRefusedError); return; } QTcpSocket *pTcpSocket = m_pSocket.take(); if (pTcpSocket) { releaseConnections(pTcpSocket); pTcpSocket->deleteLater(); } //if (m_url != url) if (Q_LIKELY(!m_pSocket)) { m_dataProcessor.clear(); m_isClosingHandshakeReceived = false; m_isClosingHandshakeSent = false; setRequestUrl(url); QString resourceName = url.path(QUrl::FullyEncoded); // Check for encoded \r\n if (resourceName.contains(QStringLiteral("%0D%0A"))) { setRequestUrl(QUrl()); //clear requestUrl setErrorString(QWebSocket::tr("Invalid resource name.")); Q_EMIT q->error(QAbstractSocket::ConnectionRefusedError); return; } if (!url.query().isEmpty()) { if (!resourceName.endsWith(QChar::fromLatin1('?'))) { resourceName.append(QChar::fromLatin1('?')); } resourceName.append(url.query(QUrl::FullyEncoded)); } if (resourceName.isEmpty()) resourceName = QStringLiteral("/"); setResourceName(resourceName); enableMasking(mask); #ifndef QT_NO_SSL if (url.scheme() == QStringLiteral("wss")) { if (!QSslSocket::supportsSsl()) { const QString message = QWebSocket::tr("SSL Sockets are not supported on this platform."); setErrorString(message); Q_EMIT q->error(QAbstractSocket::UnsupportedSocketOperationError); } else { QSslSocket *sslSocket = new QSslSocket; m_pSocket.reset(sslSocket); if (Q_LIKELY(m_pSocket)) { m_pSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1); m_pSocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1); m_pSocket->setReadBufferSize(m_readBufferSize); m_pSocket->setPauseMode(m_pauseMode); makeConnections(m_pSocket.data()); setSocketState(QAbstractSocket::ConnectingState); sslSocket->setSslConfiguration(m_configuration.m_sslConfiguration); if (Q_UNLIKELY(m_configuration.m_ignoreSslErrors)) sslSocket->ignoreSslErrors(); else sslSocket->ignoreSslErrors(m_configuration.m_ignoredSslErrors); #ifndef QT_NO_NETWORKPROXY sslSocket->setProxy(m_configuration.m_proxy); #endif sslSocket->connectToHostEncrypted(url.host(), url.port(443)); } else { const QString message = QWebSocket::tr("Out of memory."); setErrorString(message); Q_EMIT q->error(QAbstractSocket::SocketResourceError); } } } else #endif if (url.scheme() == QStringLiteral("ws")) { m_pSocket.reset(new QTcpSocket); if (Q_LIKELY(m_pSocket)) { m_pSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1); m_pSocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1); m_pSocket->setReadBufferSize(m_readBufferSize); m_pSocket->setPauseMode(m_pauseMode); makeConnections(m_pSocket.data()); setSocketState(QAbstractSocket::ConnectingState); #ifndef QT_NO_NETWORKPROXY m_pSocket->setProxy(m_configuration.m_proxy); #endif m_pSocket->connectToHost(url.host(), url.port(80)); } else { const QString message = QWebSocket::tr("Out of memory."); setErrorString(message); Q_EMIT q->error(QAbstractSocket::SocketResourceError); } } else { const QString message = QWebSocket::tr("Unsupported WebSocket scheme: %1").arg(url.scheme()); setErrorString(message); Q_EMIT q->error(QAbstractSocket::UnsupportedSocketOperationError); } } }
void MainWindow::clientLeave() { if(connectedMode=="Tcp socket (QTcpServer)") { // Wich client leave QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); if (socket == 0) // If not found return; int index=-1; for (int i = 0; i < tcpSocket.size(); ++i) { if(tcpSocket.at(i)->tcpSocket==socket) index=i; } if(index==-1) ui->statusBarApp->showMessage("Unable to locate client, internal error",10000); else { if(TcpServer.isListening()) ui->statusBarApp->showMessage("The client: "+socket->peerAddress().toString()+" as leave",10000); tcpSocket[index]->ItemInList->setIcon(QIcon(":/images/list-disconnected.png")); tcpSocket[index]->isConnected=false; tcpSocket[index]->tcpSocket=NULL; socket->deleteLater(); //compression if(tcpSocket[index]->compression!=NULL) { delete tcpSocket[index]->compression; tcpSocket[index]->compression=NULL; } if(tcpSocket[index]->compression!=NULL) { delete tcpSocket[index]->compression; tcpSocket[index]->compression=NULL; } } } if(connectedMode==COMBOBOXTEXTLOCALSOCK) { // Wich client leave QLocalSocket *socket = qobject_cast<QLocalSocket *>(sender()); if (socket == 0) // If not found return; int index=-1; for (int i = 0; i < localSocket.size(); ++i) { if(localSocket.at(i)->localSocket==socket) index=i; } if(index==-1) ui->statusBarApp->showMessage("Unable to locate client, internal error",10000); else { if(LocalServer.isListening()) ui->statusBarApp->showMessage("Client as leave",10000); localSocket[index]->ItemInList->setIcon(QIcon(":/images/list-disconnected.png")); localSocket[index]->isConnected=false; localSocket[index]->localSocket=NULL; socket->deleteLater(); } //compression if(localSocket[index]->compression!=NULL) { delete localSocket[index]->compression; localSocket[index]->compression=NULL; } if(localSocket[index]->compression!=NULL) { delete localSocket[index]->compression; localSocket[index]->compression=NULL; } } }
void HttpServer::discardClient() { QTcpSocket* socket = (QTcpSocket*)sender(); socket->deleteLater(); }
void TvEventHandler::onDisconnected() { QTcpSocket* socket = (QTcpSocket*)sender(); qCDebug(dcLgSmartTv) << "event handler -> client disconnected" << socket->peerAddress(); socket->deleteLater(); }
void CClientApp::sendCommandToServer(QVariantMap cmdMap) { QTcpSocket *socket = new QTcpSocket(this); //serverIP = "192.168.0.238"; QString command = cmdMap["command"].toString(); QJsonObject jsonObj; if (command == "listDevices") { jsonObj.insert("command", command); } else if (command == "listCommands") { QString deviceUID = cmdMap["uid"].toString(); jsonObj.insert("command", command); jsonObj.insert("uid", deviceUID); } else if (command == "sendCommandToDevice") { QString deviceUID = cmdMap["uid"].toString(); QString deviceCmd = cmdMap["deviceCmd"].toString(); QString deviceParam = cmdMap["param"].toString(); jsonObj.insert("command", command); jsonObj.insert("uid", deviceUID); jsonObj.insert("deviceCmd", deviceCmd); jsonObj.insert("param", deviceParam); } QJsonDocument doc(jsonObj); Q_EMIT m_pSender->commandReturned("SendCmdToServer: " + QString::fromLatin1(doc.toJson()) + "\n", false); QObject::connect(socket, &QTcpSocket::readyRead, [=] { QByteArray byteArray = socket->readAll(); QJsonDocument jsonDoc = QJsonDocument::fromJson(byteArray); QJsonObject jsonObj = jsonDoc.object(); QString kText("Cmd Return Result: " + QString::number(jsonObj["status"].toInt()) + "\n"); if (jsonObj["status"].toInt() == 200) { QVariantMap retMap = jsonObj.toVariantMap(); qDebug() << jsonObj["devices"].toArray().size(); parseDataToQML(retMap); kText += QString::fromLatin1(byteArray) + "\n"; } Q_EMIT m_pSender->commandReturned(kText, false); socket->disconnectFromHost(); }); QObject::connect(socket, &QTcpSocket::disconnected, [=] { socket->deleteLater(); }); socket->connectToHost(serverIP, 3479, QIODevice::ReadWrite); socket->write(doc.toJson()); bool bSentCmd = socket->waitForBytesWritten(); QString result = (bSentCmd ? "true" : "false"); Q_EMIT m_pSender->commandReturned("Cmd Sent: " + result, false); }
void CClientApp::processDeviceCommandSocket() { QTcpSocket *socket = deviceCmdServer->nextPendingConnection(); QString kText("Recieve TCP Socket\n"); Q_EMIT m_pSender->commandReturned(kText, false); QObject::connect(socket, &QTcpSocket::readyRead, [=] { QByteArray byteArray = socket->readAll(); QJsonDocument jsonDoc = QJsonDocument::fromJson(byteArray); QJsonObject jsonObj = jsonDoc.object(); QString command = jsonObj["command"].toString(); QString retJsonString; QJsonObject retJsonObj; QString kText("Recieve Cmd: " + command + "\n"); if (command == "supportCmds") { retJsonObj.insert("status", 200); QJsonArray cmdArray; /* QJsonObject cmdObj1; cmdObj1.insert("command", "adjustTemperature"); cmdObj1.insert("command_displayName", "Set Temperature"); cmdObj1.insert("param_type", "integer"); cmdObj1.insert("param_max", "100"); cmdObj1.insert("param_min", "20"); QJsonObject cmdObj2; cmdObj2.insert("command", "query"); cmdObj2.insert("command_displayName", "Query Status"); cmdObj2.insert("param_type", "none"); cmdArray.append(cmdObj1); cmdArray.append(cmdObj2); */ retJsonObj.insert("SupportCmds", cmdArray); connected = true; } else if (command == "queryDisplayInfo") { retJsonObj.insert("status", 200); QJsonArray keyArray; keyArray.append("Power"); //keyArray.append("WindStrength"); //keyArray.append("Humidity"); retJsonObj.insert("DisplayInfo", keyArray); //retJsonObj.insert("Temperature", QString::number(temperature)); //retJsonObj.insert("WindStrength", "Medium"); //retJsonObj.insert("Humidity", "60"); retJsonObj.insert("Power", "On"); } /*else if (command == "adjustTemperature") { temperature = jsonObj["param"].toString().toInt(); retJsonObj.insert("status", 200); }*/ else { kText += command + " " + jsonObj["param"].toVariant().toString() + "\n"; retJsonObj.insert("status", 200); } QJsonDocument retDoc(retJsonObj); kText += "WritingServer: " + QString::fromLatin1(retDoc.toJson()) + "\n"; socket->write(retDoc.toJson()); bool isSuccess = socket->waitForBytesWritten(); QString result = (isSuccess ? "true" : "false"); kText += "Written: " + result + "\n"; socket->disconnectFromHost(); Q_EMIT m_pSender->commandReturned(kText, false); }); QObject::connect(socket, &QTcpSocket::disconnected, [=] { socket->deleteLater(); }); }