QTcpSocket иногда зависает для динамически созданного Java-скрипта - PullRequest
1 голос
/ 10 августа 2011

Я пытаюсь подключиться к веб-сайту через прокси. Я реализовал QTcpServer и QTcpSocket. Сервер передает соединение в сокет. Это работает хорошо, но для некоторых сайтов, особенно для тех, которые динамически создавали javascript, сокет зависает в какой-то момент, и в навигаторе ничего не отображается. Прикрепите код, надеюсь, очистите.

            #include "webproxy.h"
            #include <QtNetwork>
            #include <QMessageBox>
            #include <QtGui>
            #include <QHash>


            WebProxy::WebProxy(QObject *parent,int port): QObject(parent)

                {
                    qDebug()<<" Listen...";
                    authMethod = "";
                    QTcpServer *proxyServer = new QTcpServer(this);
                    if (!proxyServer->listen(QHostAddress::Any, port)) {
                       emit error(1);

                        return;
                    }

                    connect(proxyServer, SIGNAL(newConnection()), this, SLOT(manageQuery()));
                    qDebug() << "Proxy server running at port" << proxyServer->serverPort();






            void WebProxy::manageQuery() {
                    QTcpServer *proxyServer = qobject_cast<QTcpServer*>(sender());
                    QTcpSocket *socket = proxyServer->nextPendingConnection();
                    connect(socket, SIGNAL(readyRead()), this, SLOT(processQuery()));
                    connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));

                    qDebug()<<"New connection started..."<<socket->peerAddress();
                }
            QUrl WebProxy::getUrl(QList<QByteArray > &entries)
               {

                   QByteArray method = entries.value(0);
                   QByteArray address = entries.value(1);
                   QByteArray version = entries.value(2);

                   qDebug()<<method;
                   qDebug()<<address;
                   qDebug()<<version;
                   QUrl url = QUrl::fromEncoded(address);
                   if (!url.isValid()) {

                       qWarning() << "Invalid URL:" << url;

                       return QString();
                   }


                   return url;
               }

              void WebProxy::processQuery() {

                    int wSize = 0;
                    QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
                    QByteArray requestData = socket->readAll();


             qDebug()<<"Request "<<requestData;

                    int pos = requestData.indexOf("\r\n");


                    QByteArray requestLine = requestData.left(pos);
                    requestData.remove(0, pos + 2);

                    QList<QByteArray> entries = requestLine.split(' ');
                    QByteArray method         = entries.value(0);
                    QByteArray address        = entries.value(1);
                    QByteArray version        = entries.value(2);

                    QByteArray auth;
                    QByteArray authMethod;

                    QUrl url = QUrl::fromEncoded(address);
                    if (!url.isValid()) {
                        qWarning() << "Invalid URL:" << url;
                        socket->disconnectFromHost();
                        return;
                    }

                    QString host              = url.host();


                    int port = (url.port() <= 0) ? 80 : url.port();
                    QByteArray req = url.encodedPath();
                    if (url.hasQuery())
                        req.append('?').append(url.encodedQuery());


                    requestLine = method + " " + req + " " + version + "\r\n";
                    if (!authMethod.isEmpty())
                    {
                         requestLine.append(requestLine);
                         requestLine.append(authMethod);
                         requestLine.append("\r\n");
                     }

                    QString key = host + ':' + QString::number(port);
                    QTcpSocket *proxySocket = socket->findChild<QTcpSocket*>(key);

                    if (proxySocket) {
                        proxySocket->setObjectName(key);
                        proxySocket->setProperty("url", url);
                        proxySocket->setProperty("requestData", requestData);
                        wSize = proxySocket->write(requestData);


                    } else {
                        proxySocket = new QTcpSocket(socket);
                        proxySocket->setObjectName(key);
                        proxySocket->setProperty("url", url);
                        proxySocket->setProperty("requestData", requestData);
                        connect(proxySocket, SIGNAL(connected()), this, SLOT(sendRequest()));
                        connect(proxySocket, SIGNAL(readyRead()), this, SLOT(transferData()));
                        connect(proxySocket, SIGNAL(disconnected()), this, SLOT(closeConnection()));
                        connect(proxySocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(closeConnection()));
                        proxySocket->connectToHost(host, port);
                    }
                }

            void WebProxy::sendRequest() {
                    QTcpSocket *proxySocket = qobject_cast<QTcpSocket*>(sender());
                    QByteArray requestData = proxySocket->property("requestData").toByteArray();
                    int wSize = 0;
                    wSize     = proxySocket->write(requestData);

                }

            void WebProxy::transferData() {


                    QTcpSocket *proxySocket = qobject_cast<QTcpSocket*>(sender());

                    QByteArray data = proxySocket->readAll();

            qDebug()<<"READ TRANSFER SIZE..."<<data.size();

                    QString host = proxySocket->peerAddress().toString();
                    QByteArray    filtered(data);

                    QTcpSocket *socket  = qobject_cast<QTcpSocket*>(proxySocket->parent());
                    int wSize           = 0;
                    if (!data.trimmed().isEmpty())
                    {
                        wSize = socket->write(filtered);
                        if (wSize==-1)
                             qDebug()<<"WP error";
                        else
                             qDebug()<<"TRANSFER WRITE SIZE = "<<wSize<<" READ SIZE"<<filtered.size();

                    }

                }

            void WebProxy::closeConnection() {

                    QTcpSocket *proxySocket = qobject_cast<QTcpSocket*>(sender());
                    if (proxySocket) {
                        QTcpSocket *socket = qobject_cast<QTcpSocket*>(proxySocket->parent());
                        if (socket)
                            socket->disconnectFromHost();
                        if (proxySocket->error() != QTcpSocket::RemoteHostClosedError)
                            qWarning() << "Error for:" << proxySocket->property("url").toUrl()
                                    << proxySocket->errorString();
                        proxySocket->deleteLater();;
                    }
                }

1 Ответ

1 голос
/ 16 ноября 2011

Возможно, вы захотите использовать QTcpServer в многопоточном режиме.

Подкласс QTcpServer, перегрузка QTcpServer::incomingConnection(int), создайте свой производный обработчик QThread (описанный далее) и запустите его с QThread::start

Подкласс QThread, заставьте конструктор принять int (дескриптор сокета), перегрузка QThread::run(). В функции запуска создайте QTcpSocket, вызовите QAbstractSocket::setSocketDescriptor, чтобы инициализировать сокет, подключите слоты сокетов и вызовите QThread::exec(), чтобы запустить цикл событий потока.

Убедитесь, что вы создаете сокет в run из QThread, а не в конструкторе, поэтому сокет связан с этим потоком.

Для получения более подробной информации, посмотрите пример сервера Threaded Fortune

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...