2010-06-26 3 views
19

Ich möchte eine kleine HTTP-Server-Anwendung schreiben, die HTTP-GET-Anforderungen empfängt, verarbeitet und eine Antwort sendet. Wegen der Geschichte der Anwendung würde ich Qt dafür bevorzugen, aber alles, was ich finden kann, ist die andere (häufigere) Richtung: Senden Sie eine Anfrage an einen Server und erhalten Sie eine Antwort mit QNetworkAccessManager. Was ich brauche, ist etwas wie ein Socket, das, wenn eine Anfrage eingeht, ein Objekt erzeugt, wo ich URL usw. von dieser Anfrage auswählen kann, so dass ich eine passende Antwort aussenden kann.Qt HTTP-Server?

Bin ich gerade blind oder ist nichts so in der Qt-Framework? Wenn ja, können Sie Alternativen empfehlen?

Antwort

11

Ich fand diese https://github.com/vinipsmaker/tufao, Es ist eine späte Antwort .. nicht sicher, ob es hilft.

+0

Eigentlich ist es spät, aber dieses Projekt scheint das zu sein, wonach ich gesucht habe. – grefab

14

QtWebApp ist ein HTTP-Server mit Unterstützung von GET und POST-Methode, Cookies, Sitzungen und Datei-Uploads. Die Verwendung dieser Bibliothek ist so einfach wie das Schreiben eines Java-Servlets.

Die Projektwebseite ist auf Deutsch, die herunterladbaren Dateien sind alle in Englisch, einschließlich der Dokumentation.

+3

Nice one, mit diesem für einen Web Service: http://stackoverflow.com/questions/11558237/creating-simple-webservice-in-c-qt-acting-as-server- Providing-JSON-Daten? Lq = 1 –

+0

Yep, sehr nett und einfach für eigene Projekte zu ändern. – Zeks

3

QhttpServer scheint genau das zu tun, was Sie brauchen. Leider scheint es nicht sehr aktiv zu sein.

12

ich nur die erste Version von QHttpEngine freigegeben haben, die die Lücke füllen soll, die Sie beschrieben haben. Das Ziel des Projekts ist die Bereitstellung einer extrem einfachen Gruppe von Klassen, die einen HTTP-Server bieten, der in Qt integriert ist.

Zum Beispiel dient statische Dateien von Ressourcen in der Anwendung, alles, was Sie brauchen würden, zu tun ist:

QFilesystemHandler handler(":/www"); 
QHttpServer server(&handler); 

server.listen(QHostAddress::LocalHost, 8000); 

Sie können auch eine Klasse erstellen, aus QObject abgeleitet, die ihre Schlitze als Endpunkte in einem HTTP-belichten API. Zum Beispiel:

class ApiHandler : public QObjectHandler 
{ 
    Q_OBJECT 

private slots: 

    QVariantMap doSomething(const QVariantMap &params) { 
     // do something with the parameters and return a response 
    } 
}; 

Benutzer kann dann eine POST-Anforderung an /doSomething mit den Parametern codiert als JSON senden und die Antwort erhalten, dass der Schlitz erzeugt.

Die gesamte Bibliothek ist vollständig dokumentiert und verfügt über eine umfangreiche Testumgebung. Es ist plattformübergreifend und wird offiziell unter Linux, Windows und Mac OS X getestet und unterstützt. Es gibt mindestens eine Open-Source-Anwendung, die QHttpEngine, NitroShare, verwendet.

2

Hier ist ein sehr einfacher HTTP-Webserver, der die Anzahl der Sekunden pro Sekunde aktualisiert, seit eine Verbindung im Webbrowser hergestellt wurde. Es zeigt auch die Daten an, die vom Webbrowser auf dem Bildschirm gesendet werden. Das Programm wird Port 8080 beispiels 127.0.0.1:8080

#-------------- Project file webServer3.pro ------- 
QT  += core 
QT  += network 
QT  -= gui 

TARGET = webServer3 
CONFIG += console 
CONFIG -= app_bundle 

TEMPLATE = app 


SOURCES += main.cpp 

HEADERS += \ 
myhttpserver.h 

/*------------------header file myhttpserver.h --------------*/ 
#ifndef MYHTTPSERVER 
#define MYHTTPSERVER 
#include <QCoreApplication> 
#include <QNetworkInterface> 
#include <iostream> 
#include <QObject> 
#include <QTcpSocket> 
#include <QTcpServer> 
#include <QDebug> 

class myHTTPserver : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit myHTTPserver(QObject *parent = 0); 
    ~myHTTPserver(); 
    QTcpSocket *socket ; 
public slots: 
    void myConnection(); 
private: 
    qint64 bytesAvailable() const; 
    QTcpServer *server; 
signals: 
}; 


/*------------------------main.cpp -------------------------*/ 
#include "myhttpserver.h" 

using namespace std; 
void delayms(int millisecondsToWait); 

int main(int argc, char *argv[]) 
    { 
    QCoreApplication a(argc, argv); 
    myHTTPserver server; 
    return a.exec(); 
} 

myHTTPserver::myHTTPserver(QObject *parent) : QObject(parent) 
    { 
    server = new QTcpServer(this); 
    // waiting for the web brower to make contact,this will emit signal 
    connect(server, SIGNAL(newConnection()),this, SLOT(myConnection())); 
    if(!server->listen(QHostAddress::Any,8080))cout<< "\nWeb server  could not start"; 
    else cout<<"\nWeb server is waiting for a connection on port 8080"; 
} 

void myHTTPserver::myConnection() 
    { 
    static qint16 count; //count number to be displayed on web browser 
    socket = server->nextPendingConnection(); 
    while(!(socket->waitForReadyRead(100))); //waiting for data to be read from web browser 

    char webBrowerRXData[1000]; 
    int sv=socket->read(webBrowerRXData,1000); 
    cout<<"\nreading web browser data=\n"; 
    for(int i=0;i<sv;i++)cout<<webBrowerRXData[i]; 
    cout<<"\n"; 

    socket->write("HTTP/1.1 200 OK\r\n");  // \r needs to be before \n 
    socket->write("Content-Type: text/html\r\n"); 
    socket->write("Connection: close\r\n"); 
    socket->write("Refresh: 1\r\n\r\n");  //refreshes web browser  every second. Require two \r\n. 

    socket->write("<!DOCTYPE html>\r\n"); 
    socket->write("<html><body>Number of seconds since connected.. "); 
    QByteArray str; 
    str.setNum(count++); //convert int to string 
    socket->write(str); 
    socket->write(" </body>\n</html>\n"); 

    socket->flush(); 
    connect(socket, SIGNAL(disconnected()),socket, SLOT(deleteLater())); 
    socket->disconnectFromHost(); 
} 

myHTTPserver::~myHTTPserver() 
    { 
    socket->close(); 
} 
0

Der obige einfache Server-Probleme hatte auf MSWindows laufen verwenden Betriebssysteme, wie sie nach einer Weile lockup würde. Dies lag daran, dass waitForReadyRead() auf MS-Systemen in zufälliger Weise ausgeführt wurde. Das Programm unter waitForReadyRead() wurde durch eine Ereignisschleife mit dem readyRead() - Signal ersetzt.

# Project file 
QT  += core 
QT  += network 
QT  -= gui 
TARGET = webServer 
CONFIG += console 
CONFIG -= app_bundle 
TEMPLATE = app 
SOURCES += main.cpp 
HEADERS += myhttpserver.h 

//-----------myhttpserver.h-------------- 
#ifndef MYHTTPSERVER 
#define MYHTTPSERVER 
#include <QCoreApplication> 
#include <iostream> 
#include <QObject> 
#include <QTcpSocket> 
#include <QTcpServer> 
#include <QIODevice> 

class myHTTPserver : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit myHTTPserver(QObject *parent = 0); 
    ~myHTTPserver(); 
    QTcpSocket *socket ; 
public slots: 
    void myConnection(); 
    void txRx(); 
    void closingClient(); 
private: 
    qint64 bytesAvailable() const; 
    QTcpServer *server; 
}; 
#endif // MYHTTPSERVER 

//------------------------ main.cpp ---------------------- 
#include "myhttpserver.h" 

using namespace std; 

int main(int argc, char *argv[]) 
    { 
    QCoreApplication a(argc, argv); 
    myHTTPserver server; 
    return a.exec(); 
} 

myHTTPserver::myHTTPserver(QObject *parent) : QObject(parent) 
    { 
    server = new QTcpServer(this); 
    connect(server, SIGNAL(newConnection()),this, SLOT(myConnection())); 
    if(!server->listen(QHostAddress::Any,8080))cout<< "\nWeb server  could not start"; 
    else cout<<"\nWeb server is waiting for a connection on port 8080"; 
} 

void myHTTPserver::myConnection() 
    { 
    socket = server->nextPendingConnection(); 
    connect(socket, SIGNAL(readyRead()), this, SLOT(txRx())); 
    connect(socket, SIGNAL(disconnected()), this, SLOT(closingClient())); 
} 
void myHTTPserver::txRx() 
    { 
    char webBrowerRXData[1000]; 
    int sv=socket->read(webBrowerRXData,1000); 
    cout<<"\nreading web browser data\n"; 
    for(int i=0;i<sv;i++)cout<<webBrowerRXData[i]; 
    cout<<"\n"; 

    socket->write("HTTP/1.1 200 OK\r\n");  // \r needs to be before \n 
    socket->write("Content-Type: text/html\r\n"); 
    socket->write("Connection: close\r\n"); 
    socket->write("Refresh: 1\r\n");  //refreshes web browser every second. Require two \r\n. 
    socket->write("Pragma: no-cache\r\n"); 
    socket->write("\r\n"); 
    socket->write("<!DOCTYPE html>\r\n"); 
    socket->write("<html><body>Number of seconds since connected.. "); 
    QByteArray str; 
    static qint16 count; //count number to be displayed on web browser 
    str.setNum(count++); //convert int to string 
    socket->write(str); 
    socket->disconnectFromHost(); 
} 

void myHTTPserver::closingClient() 
    { 
     socket->deleteLater(); 
} 

myHTTPserver::~myHTTPserver() 
    { 
    cout<<"\nclosing socket\n"; 
    socket->close(); 
} 
6

QttpServer = Qt + libuv + REST = API-Server

Für eine Qt API-Server, die eine large number of concurrent connections, Anfrage behandeln müssen, und was-haben-Sie ... haben wir die libuv-Bibliothek.

Obwohl libuv für NodeJS gebaut wurde, können wir Fans in Qt-land immer noch von epolls und kqueues profitieren anstatt von der standardmäßigen select-Methode.

Mehr auf Github https://github.com/supamii/QttpServer

+0

Das ist die beste Antwort hier ... nach der Untersuchung einer Reihe von Lösungen. Diese Lösung ist einfach, basierend auf den richtigen Technologien und hat saubere und einfache Beispiele. Ich werde es jetzt testen ... – rubmz

Verwandte Themen