Hallo,
weiß jemand von euch, ob man mit qt einen html Server programmieren
kann?
Es gibt im Tutorial Beispiele für einen UDP Server/Client und ein
Beispiel für einen HTML Client. Aber leider kein Beispiel für einen
Server.
Ich würde gerne mal ein wenig experimentieren und eine einfache HTML
Seite mit dem Webbrowser darstellen.
Später soll ein Mikrocontroller Daten zum HTML Server übertragen, die
dann im Browser dargestellt werden können.
Kann mir jemand helfen?
Gruß,
chris
Das Protokoll, das die Daten zum Browser übertägt, heißt HTTP, nicht
HTML. HTML ist die Markierungssprache, mit der die Daten zur
Darstellung formatiert werden. Ich nehme also an, Du suchst einen
HTTP-Server und wirst sicher leichter fündig, wenn Du danach suchst.
Was der allerdings mit QT am Hut hat (eine Library zum Aufbau von
graphischen Bedienoberflächen), ist mir auch nicht klar. Der
HTTP-Server hat einfach Seiten auszuliefern und mit graphischem
Schnickschnack wenig zu tun.
>Der HTTP-Server hat einfach Seiten auszuliefern und mit graphischem>Schnickschnack wenig zu tun.
Den graphischen Schnickschnack braucht man um verschiedene Einstellungen
des Servers verändern zu können und den Datenfluss vom Mikrocontroller
debuggen zu können.Außerdem gibt es für qt eine hervorragend
funktionierende Klasse für die serielle Schnittstelle, welche die
Verbindung zum Mikrocontroller herstellt.
>Was der allerdings mit QT am Hut hat (eine Library zum Aufbau von>graphischen Bedienoberflächen
Qt hat eine eigene Netzwerkklasse. Da ich mit qt programmiere, will ich
diese Klasse verwenden.
Innerhalb der qt-Klassen zu bleiben hat auch den Vorteil, dass ich keine
Probleme haben, irgendwelche inkompatiblen Libraries einbinden zu müssen
und das Programm Plattform unabhängig bleibt.
Hc Zimmerer schrieb:
> Was der allerdings mit QT am Hut hat (eine Library zum Aufbau von> graphischen Bedienoberflächen), ist mir auch nicht klar.
Nein, Qt besteht seit Version 4.0 aus einer Sammlung von mehreren
Libraries, von denen sich nur ein Teil um graphische Oberflächen
kümmert.
Man kann mit Qt auch problemlos einen Server schreiben, der überhaupt
nichts mit graphischen Oberflächen am Hut hat und nicht mal an irgendwas
linkt, das mit graphischen Oberflächen zu tun hat.
chris schrieb:
> Qt hat eine eigene Netzwerkklasse.
Qt hat nicht nur eine "Netzwerkklasse", sondern eine ganze Bibliothek
aus Klassen, die für Netzwerk-Kommunikation da sind.
Siehe http://doc.trolltech.com/4.6/network-programming.html> Innerhalb der qt-Klassen zu bleiben hat auch den Vorteil, dass ich keine> Probleme haben, irgendwelche inkompatiblen Libraries einbinden zu müssen> und das Programm Plattform unabhängig bleibt.
HTTP setzt auf TCP auf, und um in Qt einen TCP-Server zu schreiben,
bietet sich die Klasse (Achtung... jetzt kommt's!) QTcpServer an.
chris schrieb:
> Es gibt im Tutorial Beispiele für einen UDP Server/Client und ein> Beispiel für einen HTML Client. Aber leider kein Beispiel für einen> Server.
Du meinst so eins wie das:
http://qt.nokia.com/doc/solutions/4/qtservice/qtservice-example-server.html
Hast recht, das gibt es nicht ;-)
>Du meinst so eins wie das:>http://qt.nokia.com/doc/solutions/4/qtservice/qtse...>Hast recht, das gibt es nicht ;-)
Hmm, das scheint tatsächlich ein Beispiel für einen HTTP-Server zu sein.
Aber nenne mich "Weichei": ich habe mich schon ein wenig an die
Entwicklungsoberfäche "qt-creator" von qt gewöhnt. Dort findet man ein
schönes Menü mit Beispielprogrammen. Die kann man einfach anklicken und
mit dem grünen "Run" Button kompilieren und laufen lassen. Wunderbar,
das ist fast so, als wenn man ein Auto, bevor man damit losfahren möchte
gar nicht mehr zusammenschrauben müsste, sondern einfach einsteigt
fährt. ;-)
Mit der Erstellung von Make-Files habe ich es noch nicht so. Vielleicht
kannst Du mir einen Tipp geben wie alle Files zusammen mit der *.pro zu
erstellen sind, damit das Programm einfach zu kompilieren ist.
Gruß,
chris
Hmm, da müste ich ja qmake lernen, wo ich doch die schöne Oberfläche von
qt-creator habe.
Jetz bin ich einfach mal so vorgegangen: In den Beispielfiles des
qt-Creators gibt es einen TCP-Server, der sendet ein paar Sprüche bei
einem TCP-Request.
Dort habe ich einfach den Beispielcode für "GET" aus dem obigen Link
kopiert. Ich kann per telnet den Server kontaktieren, aber er liefert
keine Antwort. Habt Ihr eine Ahnung warum?
Das hilft mir jetzt im Moment nicht weiter.
Was ich brauche ist jemand der mir sagt, warum in meinem oben geposteten
Programm das Signal
connect(tcpServer, SIGNAL(readyRead()), this, SLOT(sendFortune()));
meine Funktion
void Server::sendFortune() {
..}
nicht auslöst, wenn mit telnet ein Kommando an den Server gesendet wird.
Der Server selbst läuft, da man ihn mit telnet kontaktieren kann. Wird
der Server mit dem "Quit" Button beendet, merkt das telnet und schließt
auch ganz korrekt die Verbindung.
>Tipp: Mit http://www.w3.org/Protocols/HTTP/AsImplemented.html und dich>dann almaehlich bis zu HTTP/1.0 weiterentwickeln.
Wobei, der Link ist gar nicht so schlecht.
Es gibt nämlich noch ein kleines Problem: Wenn sich Web-Inhalte auf dem
HTTP ändern ( also z.B. der Mikrocontroller einen anderen Temperaturwert
anzeigen will ) müsste der Browser die Seite ja neu laden. Deshalb die
Frage: Kann man den Browser dazu bringen, die Seite zyklisch
anzufordern?
Hmm, es scheint so, als wenn ich nicht der Einzige bin, der versucht hat
das Fortune-Server Example von qt umzubauen:
http://www.c-plusplus.de/forum/viewtopic-var-t-is-250414.html
Allerdings tritt dort genau das gleich Problem auf: das Siganl
readyRead() scheint nicht zu funktionieren.
@Rolf Magnus (Gast)
Siehst Du, genau da liegt dann das Problem: Man kann Stunden damit
verbraten, irgend welche Fehler in Beispielen zu suchen, die eben nicht
als lauffähige Projektdatei vorhanden sind. Das Problem liegt nämlich in
diesem Fall jetzt nicht mehr am zusammengestückelten Code, sondern an
irgend einer Eigenschaft von QtServer mit der auch andere Leute Probleme
haben.
Ist zwar etwas offtopic: Aber muss man sich für einen einfachen HTTP-
Server unbedingt durch Qt udn C++ quälen? In Python, Perl oder Ruby geht
das ratzfatz ohne viel Tipparbeit. Hier ein Beispiel in Python, das die
aktuelle Uhrzeit auf einer Webseite anzeigt:
1
from BaseHTTPServer import *
2
from time import strftime
3
4
page = """
5
<html>
6
<metahttp-equiv="refresh"content="60"/>
7
<h1>Uhrzeit</h1>
8
Es ist jetzt %s.
9
</html>
10
"""
11
12
class MyHTTPRequestHandler(BaseHTTPRequestHandler):
Du hast schon Recht: mit Python geht es einfacher.
Ich habe mir eine ganze Weile überlegt, ob Python nicht das Mittel der
Wahl ist. Bei meinem Projekt sollte später noch Datengraph dazu kommen.
In der Grundausstattung hat Python soweit ich das verstanden habe aber
keine Graphik. Man muss dann erst zusätzliche Libraries installieren.
Mein Ziel ist es aber, ein kompaktes, in sich geschlossenes Programm
ohne große Installationsorgien zu haben.
@Yalu X
witzig, spaßeshalber habe ich Dein Python Script mal ausprobiert und es
kann tatsächlich die Uhrzeit im Browser anzeigen, wenn ich die lokale
IP-Adresse eingebe:
http://192.168.1.10:8080/
Jetzt wäre es spannend ein Python-Script, das Daten von der seriellen
Schnittstelle einliest und im Server mit Browser-Refresh darstellt mit
dem Aufwand in c++ zu vergleichen.
sepp schrieb:
> Was ich brauche ist jemand der mir sagt, warum in meinem oben geposteten> Programm das Signal>> connect(tcpServer, SIGNAL(readyRead()), this, SLOT(sendFortune()));>> meine Funktion>> void Server::sendFortune() {> ..}>> nicht auslöst, wenn mit telnet ein Kommando an den Server gesendet wird.
Das liegt ganz einfach daran, daß es dieses Signal nicht gibt, wie auch
die Ausgabe des Programms schon sagt. Auch mit Qt wird man sich nicht
aus Fragmenten aus völlig verschiedenen Programmen einen HTTP-Server
basteln können, ohne auch nur einen Blick in die Doku zu werfen.
Lies wenigstens mal
http://doc.trolltech.com/4.6/network-programming.html#using-tcp-with-qtcpsocket-and-qtcpserver
Das da ist übrigens nicht gut:
1
server.cpp: In member function ‘void Server::sendFortune()’:
2
server.cpp:148: warning: format ‘%s’ expects type ‘char*’, but argument 2 has type ‘QChar*’
Hallo Magnus,
danke für die Hinweise. Ich habe jetzt schon eine ganze Weile probiert,
bin aber leider nicht weitergekommen.
Dafür habe ich das obige Python Beispiel für den Server erweitert ( ich
habe bis jetzt noch nie was mit Python zu tun gehabt ).
Und ich muss sagen, es ist wirklich beeindruckend: ich konnte auf die
Schnelle einen seriell nach http Konverter basteln. Die Daten von meinem
Arduino Board, welche über die USB-Schnittstelle kommen, werden jetzt im
Browser dargestellt. Das ganze funktioniert auch noch vom Rechner im
Nachbarzimmer aus. Wenn ich die Portfreigabe im Router noch schaffe,
dann wahrscheinlich auf der ganzen Welt ...
Hier der Code:
1
from BaseHTTPServer import *
2
from time import strftime
3
import serial
4
5
SER_PORT = '/dev/ttyUSB0'
6
SER_BAUD = 9600
7
ser = None
8
9
page = """
10
<html>
11
<metahttp-equiv="refresh"content="3"/>
12
<h1>python serial input http server</h1>
13
<h4>chris, march 2010 </h4>
14
15
%s
16
17
</html>
18
"""
19
20
textBuffer="<p> trying serial port:" + SER_PORT + "</p>"
21
22
class MyHTTPRequestHandler(BaseHTTPRequestHandler):
23
def do_GET(self):
24
global textBuffer
25
#self.wfile.write(page % strftime("%H:%M"))
26
self.wfile.write(page % textBuffer)
27
textBuffer=textBuffer+ser.read(10)
28
29
def cb_opendat():
30
print "opendat"
31
32
def cb_quit():
33
print "quit - cleanup"
34
ser.close()
35
root.quit()
36
37
def openSerial():
38
global ser
39
ser = serial.Serial(SER_PORT, SER_BAUD, timeout = 1)