2011-08-10 2 views
1

프록시를 통해 웹 사이트에 연결하려고합니다. 나는 QTcpServer와 QTcpSocket을 구현했다. 서버가 소켓에 연결을 전달합니다. 잘 작동하지만 일부 사이트에서는 동적으로 생성 된 자바 스크립트가있는 사이트의 경우 소켓이 멈 춥니 다. 탐색기에 아무것도 표시되지 않습니다. 코드를 첨부하십시오.가끔 동적으로 생성 된 자바 스크립트에 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 파생 핸들러를 작성 (다음에 설명) 및 QThread::start

서브 클래스 QThread로 시작, 생성자가 int (소켓 기술자를) 받아 들일 수 있도록, QThread::run() 과부하. 실행 함수에서 QTcpSocket을 만들고 QAbstractSocket::setSocketDescriptor을 호출하여 소켓을 초기화하고 소켓 슬롯을 연결 한 다음 QThread::exec()을 호출하여 스레드 이벤트 루프를 시작합니다.

소켓이 해당 스레드와 연결되도록 QThread 인 소켓을 생성자가 아니라 생성해야합니다.

자세한 내용은 Threaded Fortune Server Example

관련 문제