// ---------------------------------------------------------------------- void DServer::deleteClientSocket() { QTcpSocket* pClientSocket = (QTcpSocket*)sender(); pClientSockets.remove(pClientSockets.indexOf(pClientSocket)); pClientSocket->disconnect(); pClientSocket->deleteLater(); m_ptxt->append(QString::number( pClientSocket->localPort())+" is disconnected"); }
void NetworkServer::slotConnectionEnded() { for(int i=0; i < mTcpSockets.size(); i++) { QTcpSocket* socket = mTcpSockets.at(i); if(socket->state() == QAbstractSocket::ClosingState || socket->state() == QAbstractSocket::UnconnectedState) { qDebug() << "NetworkServer::slotConnectionEnded(): connection from" << socket->peerAddress() << socket->peerPort() << "closed, removing socket."; socket->disconnect(); socket->deleteLater(); mTcpSockets.removeAt(i); } } }
void ProtocolSocket::setSocket(QTcpSocket *socket) { if (socket && socket->state() != QAbstractSocket::ConnectedState) { qWarning() << "BUG: ProtocolSocket::setSocket with unconnected socket"; socket = 0; } if (socket == m_socket) return; bool wasConnected = isConnected(); if (m_socket) { /* The existing socket is replaced, and all pending commands * are considered failed. This could be improved on. */ QTcpSocket *oldSocket = m_socket; m_socket = 0; oldSocket->disconnect(this); // XXX can this be avoided if none are sent yet? abortCommands(); oldSocket->abort(); oldSocket->deleteLater(); } m_socket = socket; if (socket) { socket->setParent(this); connect(socket, SIGNAL(readyRead()), this, SLOT(read())); // QueuedConnection used to make sure socket states are updated first connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()), Qt::QueuedConnection); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketDisconnected()), Qt::QueuedConnection); if (!wasConnected) { m_connectedTime.restart(); emit connected(); } flushCommands(); read(); } else { emit disconnected(); } emit socketChanged(); }
void TestHTTPServer::disconnected() { QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender()); if (!socket) return; dataCache.remove(socket); for (int ii = 0; ii < toSend.count(); ++ii) { if (toSend.at(ii).first == socket) { toSend.removeAt(ii); --ii; } } socket->disconnect(); socket->deleteLater(); }
/** * ブラウザとのソケットと本来のホストとのソケットを接続するトンネルを作成 */ void YASWebProxy::openTunnel() { QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender()); QByteArray data = socket->readAll(); HttpParser* parser = socket->findChild<HttpParser*>("requestParser"); parser->input(data); QTcpSocket* proxySocket = socket->findChild<QTcpSocket*>("tunnel"); if (!proxySocket) { // 本来のホストへのソケットを作成 proxySocket = new QTcpSocket(socket); proxySocket->setObjectName("tunnel"); proxySocket->connectToHost(parser->url.host(), parser->url.port(80)); connect(proxySocket, SIGNAL(disconnected()), this, SLOT(closeProxySocket())); connect(proxySocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(closeProxySocket())); connect(proxySocket, SIGNAL(readyRead()), this, SLOT(forwardResponse())); if (parser->method == "CONNECT") { disconnect(socket, SIGNAL(readyRead()), this, SLOT(openTunnel())); connect(socket, SIGNAL(readyRead()), this, SLOT(forwardRequest())); } else { HttpParser* resParser = new HttpParser(HttpParser::RESPONSE, proxySocket); resParser->setObjectName("responseParser"); resParser->setProperty("url", parser->url.toString()); connect(resParser, SIGNAL(completeMessage(QByteArray)), this, SLOT(onResponse(QByteArray))); } } if (proxySocket->waitForConnected()) { if (parser->method == "CONNECT") { socket->write("HTTP/1.0 200 Connection established\r\n\r\n"); } else { proxySocket->write(parser->dequeueData()); } } else { proxySocket->disconnect(); } }
void Tunneld::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 QTimer *t = new QTimer(); auto later_close_timeout = [enpeer, t]() { 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; } 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()); t->deleteLater(); }; qDebug()<<"last recv time:"<<enpeer->incomingPeerID <<enetx_time_diff(enpeer->lastReceiveTime, enet_time_get()); // QTimer::singleShot(5678, later_close_timeout); t->setInterval(5678); t->setSingleShot(true); QObject::connect(t, &QTimer::timeout, later_close_timeout); t->start(); }