2011-08-10 8 views
1

プロキシ経由でWebサイトに接続しようとしています。私はQTcpServerとQTcpSocketを実装しました。 サーバーは接続をソケットに渡します。 それはうまくいくが、いくつかのサイトでは、動的に作成されたjavascriptを持っているサイトでは、ソケットが何らかの点で止まり、ナビゲータに何も表示されない。 コードを添付してください。ダイナミックに作成されたJavaスクリプトのQTcpSocketが時々スタックする

  #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

マルチスレッドの方法でQTcpServerを使用します。

サブクラスQTcpServer、過負荷QTcpServer::incomingConnection(int)、(次に説明する)あなたのQThread派生ハンドラを作成し、コンストラクタはint(ソケット記述子を)受け入れる行い、QThread::start

サブクラスQThreadでそれを起動し、QThread::run()をオーバーロード。実行機能でQTcpSocketを作成し、QAbstractSocket::setSocketDescriptorを呼び出してソケットを初期化し、ソケットスロットを接続してQThread::exec()を呼び出してスレッドイベントループを開始します。

ソケットがコンストラクタではなくQThreadrunに作成されていることを確認してください。そうすれば、ソケットはそのスレッドに関連付けられます。

詳しくは、Threaded Fortune Server Example

をご覧ください。
関連する問題