-
Hi an Alle!
Wie im Topic zu lesen soll dieses Programm einen kleinen Webserver darstellen, der zunächst einmal nur die Seite bei einem Request in den Socket zurückschreiben soll.
Leider scheint hier irgendwo ein Fehler zu sein, da ich, wenn ich die Seite 127.0.0.1 aufrufe, eine Fehlermeldung im Browser bekomme.
Ich stehe nur etwas auf dem Schlauch, da die Kontrollausgaben im Programm so aussehen, wie ich sie mir vorgestellt habe.
Wisst ihr vielleicht weiter?
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
// // Programm: einfacher Webserver // Funktiosumfang: Lauschen auf Port 80, bei Anfrage einer Seite, // diese zum anfragenden Client zurücksenden //---------------------------------------------------------------------------- // Einbinden der Headerdateien #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <sys/wait.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> // Prototypen der verwendeten Funktionen int deploy_server(); void process_request(int result_accept); int main() { int sock=-1, source=0, result_accept=0, pid=-1, len_addr=0, status=0; struct sockaddr_in requestor; printf(".\n"); printf(".\n"); printf("Webserver v1.0 gestartet\n"); printf(".\n"); printf(".\n"); do { sock = deploy_server(); if(sock<0) { printf("Fehler beim Deployen des Servers!\n"); printf("<RETURN> für Neuversuch\n\n"); getchar(); } }while(sock < 0); while(1) { len_addr = sizeof(source); result_accept = accept(sock, (struct sockaddr*) &source, &len_addr); if(-1 == result_accept) { printf("Fehler beim Verbindungsaufbau\n"); } else { printf("Verbindungsaufbau erfolgreich\n"); } pid = fork(); if(-1 == pid) { printf("Fehler beim erstellen des Sohnprozesses!\n"); } if(0 == pid) { process_request(result_accept); exit(0); waitpid(-1, &status, WNOHANG); printf("Status: %d", status); } close(result_accept); } } int deploy_server() { int sock, result_bind=5; struct sockaddr_in adressinfo; sock = socket(AF_INET, SOCK_STREAM, 0); bzero(&adressinfo, sizeof(adressinfo)); adressinfo.sin_family = AF_INET; adressinfo.sin_port = htons(80); adressinfo.sin_addr.s_addr = INADDR_ANY; result_bind = bind(sock, (struct sockaddr*) &adressinfo, sizeof(adressinfo)); if(result_bind == -1) { printf("Fehler bei Bind"); return -1; } listen(sock, 2); return(sock); } void process_request(int sock) { char sendbuffer[8096], request[8096], filename[8096], buffer; int i=0, k=0,f=0, ext_laenge=0, anzahl=0, file_descript=0; char get_ext[4]; bzero(&request, sizeof(request)); bzero(&filename, sizeof(filename)); while(i < sizeof(request)-1) // solange die Länge des Strings nicht überschritten wird { if( read(sock, &buffer, 1) > 0 // Solange ein Zeichen gelesen werden kann && buffer != '\n' // UND kein Zeilenumbruch && buffer != '\r') { request[i] = buffer; // weiter einlesen i++; } else { request[i] = '\0'; // Sonst String abschließen break; // und Schleife abbrechen } } // Kontrollausgabe der Anfrage for(k=0; k< sizeof(request); k++) printf("%c", request[k]); printf("\n\n"); // Prüfen ob Get-Anfrage (nicht Case-Sensitive) if(!strncmp(request, "GET ", 4) || !strncmp(request, "get ", 4)) // falls GET { i=5; // Startwert des Index, GET wird ignoriert if(!strncmp(&request[5], " ", 1)) // Wenn keine Seite angegeben { strcpy(request, "GET /index.html"); // String auf index.html setzen } while(strncmp(&request[i], " ", 1) != 0) // SOLANGE KEIN Leerzeichen gefunden { strncpy(&filename[f], &request[i], 1); // Zeichen an Filename anhängen f++; i++; } // Extensions prüfen // FEHLT NOCH // FEHLT NOCH // FEHLT NOCH // FEHLT NOCH printf("OPENING: >%s<\n", filename); file_descript=open(filename, O_RDONLY); // Angefordertes File öffnen if(file_descript != -1) { /* while(anzahl=read(file_descript, sendbuffer, sizeof(sendbuffer))) write(sock, sendbuffer, anzahl);*/ write(sock, sendbuffer, read(file_descript, sendbuffer, sizeof(sendbuffer))); close(file_descript); } else printf("Fehler! File konnte nicht geöffnet werden!\n"); close(sock); printf("--> ENDE \n"); } else printf("Nur GET-Anfragen werden bearbeitet!\n"); }
Desweiteren bin ich mir nicht ganz sicher, ob die Anweisung close(sock); (*in Zeile 185) hier an der richtigen Stelle steht, da dort der socket ja eignetlich immer offen gehalten werden sollte?!
Wo kann ich sie sonst unterbringen? Das Programm wird auf einem SuSe-System ausgefürt und mit Strg+C terminiert. Ich habe die Vermutung, dass hier eventuell der Fehler steckt, da nach einiger Zeit der Aufruf zunächst funktioniert (Seite wird an Client zurückgegeben) und anschließend für eine längere Zeit nicht mehr.
Gruß
huebstAr
-
13.12.11 16:48 #2
- Registriert seit
- Jun 2007
- Ort
- Passau (Niederbayern)
- Beiträge
- 1.394
Hi,
welche Fehlermeldung? Hast du schon mal den Request über telnet abgesetzt und geschaut was wirklich vom Server kommt?
Welchen Standard folgst du? HTTP/1.0 oder HTTP/1.1?
Gruß
BKÜber eine gute Bewertung freut sich jeder ;)
Bitte erledigte Threads als "Erledigt" markieren.
"Though a program be but three lines long, someday it will have to be maintained.''
-- Geoffrey James, "The Tao of Programming"
-
-
Hi
Dein Server schließt nach Übertragung die Socketverbindung von sich aus.
Diesen Teil sollte der Browser übernehmen.
Sonst kann es passieren, dass nicht alle Byte ankommen.
Also nach Übertragung weitere Befehle abwarten.
Wenn recv mit einem Fehlerreturnwert kommt (macht es bei geschlossener Verbindung),
dann Ende.
GrußNetiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
Hi!
Also verstehe ich nun richtig: Das close(socket); sollte nicht an dieser Stelle stehen, sondern wenn von dem Browser (Client) eine Fehlermeldung kommt, aufgerufen werden?
€: Nein, falsch verstanden, ich Denke du meinst das close(result_accept); !?Geändert von huebstAr (13.12.11 um 18:16 Uhr)
-
Beides nur so halb.
Erstens handelt es sich bei result_accept und sock in process_request
um den gleichen Socket.
Dann schließt du (nicht in jedem Fall, aber doch) sock schon in process_request,
und dann schließt du result_accept nocheinmal.
Drittens soll das nicht gemacht werden, wenn die Fehlermeldung kommt,
sondern eben, um diese zu verhindern.
Der Browser schickt "GET irgendwas".
Dein Server schickt den Inhalt (wo ist eigentlich der Header
).
Wenn der Browser alles hat, schließt der die Verbindung.
Der Server muss warten, ob geschlossen wird oder weitere Befehle kommen.
Abe wo der Head ist, wäre interessant...Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
Danke erstmal!
Leuchtet mir so halb ein. Wenn ich den Socket schon geschlossen habe und dann nochmals schließe (wobei aber noch keine neue Socket-Nr eingetragen wurde), passiert ja im Prinzip nichts, oder?
Hier weiß ich nicht, was du damit meinst. Der Socket soll doch nach jedem mal geschlossen werden, falls eine Seite übertragen wurde. Sofern bin ich mir nun nicht ganz sicher, was du meinst mit "Fehlermeldung verhindern".
Meinst du den Kopf der HTML-Seite? Habe ich nun nachträglich eingefügt. Das dürfte ja aber nicht zu der nicht-anzeige führen, oder?
Wie kann ich auf dieses Ereignis warten? Was schickt der Browser denn für eine Stop-Condition? Der Server soll nur eine Seite anzeigen, weiteres nicht.
Gruß
-
Zum Schließen: Ob da was passiert oder nicht, ist nicht garantiert.
Das Programm könnte auch ebensogut abstürzen.
Mit Header meinte ich den des HTTP-Protokolls...
hier das Inhaltsverzeichnis
Genauer das:
http://www.w3.org/Protocols/rfc2616/...sec4.html#sec4
Und wie man erkennt, ob die Gegenseite den Socket schließt:
recv liefert einen Fehlercode.
read ist sowieso fehl am Platz.Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
14.12.11 10:54 #9
- Registriert seit
- Jun 2007
- Ort
- Passau (Niederbayern)
- Beiträge
- 1.394
Hi,
zuerstmal: Es ist egal, ob der Server oder der Client die Verbindung schließt.
Bei persistenten Verbindungen (ab HTTP/1.1) wird die Verbindung (mit einem richtigen Header) zum Beispiel primär vom Client geschlossen, wenn der nichts mehr zu sagen hat. Bei HTTP/1.0 oder nicht persistenten Verbindungen schließt der Server die Verbindung, sobald er alle Daten gesendet hat. Der entsprechende Header nennt sich "Connection" und hat dann entweder "close" oder "Keep-Alive" als Wert.
Ich denke mal, dass du das HTTP-Protokoll nicht RFC-konform umsetzt und sich daher der Firefox weigert was anzuzeigen.
Wie sieht dein Request an den Server und die Antwort darauf exakt aus?
Es sollte in etwa so aussehen:
Code :1 2 3 4 5 6 7 8 9 10 11 12
/* REQUEST START */ GET /index.html HTTP/1.0 Zusaetzliche-Header: Felder /* REQUEST ENDE */ /* ANSWER START */ HTTP/1.0 200 OK Content-Type: text/plain Content-Length: 29 dies ist der text der antwort /* ANSWER ENDE*/
Woruaf ich dich besonders hinweisen möchte: Zwischen dem Header und dem Body steht eine Leerzeile (genauso am Ende des Requests) und bei der Antwort muss das Feld "Content-Length" gesetzt sein. Ob der "Content-Type" auch benötigt wird, kann ich dir ausm Gedächtnis leider nicht sagen, würde den aber trotzdem mitsenden.
Edit: Hier noch ein bisschen was zum Lesen für dich: RFC 2616
Gruß,
BKGeändert von Bratkartoffel (14.12.11 um 11:01 Uhr)
Über eine gute Bewertung freut sich jeder ;)
Bitte erledigte Threads als "Erledigt" markieren.
"Though a program be but three lines long, someday it will have to be maintained.''
-- Geoffrey James, "The Tao of Programming"
-
Hi!
Danke erstmal für die Ausführung. Habe nun (erst einmal) den Header so eingefügt. Da ich noch einige kleiner Änderungen durchgeführt habe, schreibe ich hier nochmal den aktuellen Code rein:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
//---------------------------------------------------------------------------- // Einbinden der Headerdateien #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <sys/wait.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> // Prototypen der verwendeten Funktionen int deploy_server(); void process_request(int result_accept); int main() { int sock=-1, source=0, result_accept=0, pid=-1, len_addr=0, status=0; struct sockaddr_in requestor; printf(".\n"); printf(".\n"); printf("Webserver v1.0 gestartet\n"); printf(".\n"); printf(".\n"); do { sock = deploy_server(); if(sock<0) { printf("Fehler beim Deployen des Servers!\n"); printf("<RETURN> für Neuversuch\n\n"); getchar(); } }while(sock < 0); while(1) { len_addr = sizeof(source); result_accept = accept(sock, (struct sockaddr*) &source, &len_addr); if(-1 == result_accept) { printf("Fehler beim Verbindungsaufbau\n"); } else { printf("Verbindungsaufbau erfolgreich\n"); } pid = fork(); if(-1 == pid) { printf("Fehler beim erstellen des Sohnprozesses!\n"); } if(0 == pid) { process_request(result_accept); exit(0); waitpid(-1, &status, WNOHANG); printf("Status: %d", status); } close(result_accept); } } int deploy_server() { int sock, result_bind=5; struct sockaddr_in adressinfo; sock = socket(AF_INET, SOCK_STREAM, 0); bzero(&adressinfo, sizeof(adressinfo)); adressinfo.sin_family = AF_INET; adressinfo.sin_port = htons(80); adressinfo.sin_addr.s_addr = INADDR_ANY; result_bind = bind(sock, (struct sockaddr*) &adressinfo, sizeof(adressinfo)); if(result_bind == -1) { printf("Fehler bei Bind"); return -1; } listen(sock, 5); return(sock); } void process_request(int sock) { char sendbuffer[8096], request[8096], filename[8096], buffer; int i=0, k=0,f=0, ext_laenge=0, anzahl=0, file_descript=0; char ex_extension[4]; bzero(&request, sizeof(request)); bzero(&filename, sizeof(filename)); bzero(&sendbuffer, sizeof(sendbuffer)); bzero(&ex_extension, sizeof(ex_extension)); while(i < sizeof(request)-1) // solange die Länge des Strings nicht überschritten wird { if( read(sock, &buffer, 1) > 0 // Solange ein Zeichen gelesen werden kann && buffer != '\n' // UND kein Zeilenumbruch && buffer != '\r') { request[i] = buffer; // weiter einlesen i++; } else { request[i] = '\0'; // Sonst String abschließen break; // und Schleife abbrechen } } // Kontrollausgabe der Anfrage for(k=0; k< sizeof(request); k++) printf("%c", request[k]); printf("\n\n"); // Prüfen ob Get-Anfrage (nicht Case-Sensitive) if(!strncmp(request, "GET ", 4) || !strncmp(request, "get ", 4)) // falls GET { i=5; // Startwert des Index, GET wird ignoriert f=0; if(!strncmp(&request[5], "\0", 1) || !strncmp(&request[5], "\0", 1)) // Wenn keine Seite angegeben { printf("keine page\n"); strcpy(request, "get /index.html "); // String auf index.html setzen } while(strncmp(&request[i], " ", 1)) // SOLANGE KEIN Leerzeichen erreicht { strncpy(&filename[f], &request[i], 1); // Zeichen an Filename anhängen f++; i++; } i=0; // Extensions extrahieren while(strncmp(&filename[i], ".", 1)) // Punkt suchen { i++; } strcpy(ex_extension, &filename[i+1]); // Fileextension extrahieren // Extension zuordnen // FEHLT // FEHLT // FEHLT printf("OPENING: >%s<\n", filename); printf("EXTENSION: >%s<\n", ex_extension); file_descript=open(filename, O_RDONLY); // Angefordertes File öffnen if(file_descript != -1) { sprintf(request, "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"); anzahl=read(file_descript, sendbuffer, sizeof(sendbuffer)); { write(sock, sendbuffer, anzahl); } close(file_descript); } else printf("Fehler! File konnte nicht geöffnet werden!\n"); printf("--> ENDE \n"); } else printf("Nur GET-Anfragen werden bearbeitet!\n"); }
Nun, das Programm tut bis hierhin was es soll, jedenfalls via Telnet. Das Problem ist, dass der FF scheinbar HTTPTML/1.1 requestet.
Kann man den Firefox irgendwie 'toleranter' schalten?
Das interessante ist, dass durchschnittlich jedes 2. Mal die Page angezeigt wird, wenn ich einfach nochmal einen Refresh durchfuehre, kann es sein, dass die Page mit der Fehlermeldung "The connection was reset" terminiert wird.
Im Fenster des Programms "webserver" auf Konsolenebene wird jedoch der richtige Request / bzw. nichts auffaelliges angezeigt.
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
OPENING: >index.html< EXTENSION: >html< --> ENDE Verbindungsaufbau erfolgreich GET /index.html HTTP/1.1 OPENING: >index.html< EXTENSION: >html< --> ENDE Verbindungsaufbau erfolgreich GET /index.html HTTP/1.1 OPENING: >index.html< EXTENSION: >html< --> ENDE Verbindungsaufbau erfolgreich GET /index.html HTTP/1.1 OPENING: >index.html< EXTENSION: >html< --> ENDE Verbindungsaufbau erfolgreich GET /index.html HTTP/1.1 OPENING: >index.html< EXTENSION: >html< --> ENDE
Hat da jemand ne Idee?Geändert von huebstAr (14.12.11 um 22:11 Uhr)
-
HTML1.1: Du meinst HTTP. Großer Unterschied.
Kannst du die Telneteinagbe/ausgabe auch mal zeigen?
PS: content-length...
Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
-
Also, nocheinmal:
Außer dem Content-Type musst du die Content-Length angeben.
Als Zahl, wieviel Chars (oder Byte?, muss nachschauen) die Datei hat.
Der Zeichensatz ist auch eines der essentiellen Sachen, die möglichst dabei sein sollten.
Dein Header wird nirgends geschickt,
Zum Senden (Header und Daten) über den Socket solltest du Socketfunktionen verwenden und deren Eigenheiten beachten (uU. wird nicht mit einem Aufruf alles gesendet).
Und wenn FF HTTP1.1 verlangt (was übrigens nicht umstellbar ist und auch verwendet werden sollte, da 1.0 mit heutigem Zeug Probleme hat), dann gib ihm im Header doch HTTP1.1, nicht 1.0.Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
-
15.12.11 11:06 #14
- Registriert seit
- Jun 2007
- Ort
- Passau (Niederbayern)
- Beiträge
- 1.394
Hi,
dem Firefox ist es relativ egal, ob er nun HTTP/1.0 oder 1.1 Antworten bekommt. Ich würde auch auf die fehlende Angabe des "Content-Length" Headers in der Antwort tippen.
Grüße,
BKÜber eine gute Bewertung freut sich jeder ;)
Bitte erledigte Threads als "Erledigt" markieren.
"Though a program be but three lines long, someday it will have to be maintained.''
-- Geoffrey James, "The Tao of Programming"
-
Moin Zusammen!
Danke erstmal für die Tipps, habe mich noch ein wenig damit beschäftigt und bin auch 'ne Ecke weiter gekommen (meiner Ansicht nach zumindest
)
Also stand der Dinge:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
// //---------------------------------------------------------------------------- // Einbinden der Headerdateien #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <sys/wait.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> // Prototypen der verwendeten Funktionen int deploy_server(); void process_request(int result_accept); // Struktur mit erlaubten MIME-Types struct { char *ext; char *filetype; } extensions[] = { {"gif", "image/gif"}, {"jpg", "image/jpg"}, {"jpeg", "image/jpeg"}, {"png", "image/png"}, {"zip", "image/zip"}, {"gz", "image/gz"}, {"tar", "image/tar"}, {"htm", "text/htm"}, {"html", "text/html"}, {0,0} }; int main() { int sock=-1, source=0, result_accept=0, pid=-1, len_addr=0, status=0; struct sockaddr_in requestor; printf(".\n"); printf(".\n"); printf("Webserver v1.3 gestartet\n"); printf(".\n"); printf(".\n"); do { sock = deploy_server(); if(sock<0) { printf("Fehler beim Deployen des Servers!\n"); printf("<RETURN> für Neuversuch\n\n"); getchar(); } }while(sock < 0); while(1) { len_addr = sizeof(source); result_accept = accept(sock, (struct sockaddr*) &source, &len_addr); if(-1 == result_accept) { printf("Fehler beim Verbindungsaufbau\n"); } else { printf("Verbindungsaufbau erfolgreich\n"); } pid = fork(); if(-1 == pid) { printf("Fehler beim erstellen des Sohnprozesses!\n"); } if(0 == pid) // wenn Sohnprozesses { process_request(result_accept); exit(0); } waitpid(-1, &status, WNOHANG); close(result_accept); } } int deploy_server() { int sock, result_bind=5; struct sockaddr_in adressinfo; sock = socket(AF_INET, SOCK_STREAM, 0); bzero(&adressinfo, sizeof(adressinfo)); adressinfo.sin_family = AF_INET; adressinfo.sin_port = htons(80); adressinfo.sin_addr.s_addr = INADDR_ANY; result_bind = bind(sock, (struct sockaddr*) &adressinfo, sizeof(adressinfo)); if(result_bind == -1) { printf("Fehler bei Bind"); return -1; } listen(sock, 5); return(sock); } void process_request(int sock) { char sendbuffer[8096], request[8096], filename[8096], buffer, ex_extension[4]; int i=0, k=0,f=0, ext_laenge=0, anzahl=0, file_descript=0; char *format; bzero(&request, sizeof(request)); bzero(&filename, sizeof(filename)); bzero(&sendbuffer, sizeof(sendbuffer)); bzero(&ex_extension, sizeof(ex_extension)); while(i < sizeof(request)-1) // solange die Länge des Strings nicht überschritten wird { if( read(sock, &buffer, 1) > 0 // Solange ein Zeichen gelesen werden kann && buffer != '\n' // UND kein Zeilenumbruch && buffer != '\r') { request[i] = buffer; // weiter einlesen i++; } else { request[i] = '\0'; // Sonst String abschließen break; // und Schleife abbrechen } } // Kontrollausgabe der Anfrage for(k=0; k< sizeof(request); k++) printf("%c", request[k]); printf("\n\n"); // Prüfen ob Get-Anfrage (nicht Case-Sensitive) if(!strncmp(request, "GET ", 4) || !strncmp(request, "get ", 4)) // falls GET { i=5; // Startwert des Index, GET wird ignoriert f=0; if(!strncmp(&request[5], "\0", 1) || !strncmp(&request[5], " ", 1)) // Wenn keine Seite angegeben { strcpy(request, "GET /index.html"); // String auf index.html setzen } while(strncmp(&request[i], " ", 1)) // SOLANGE KEIN Leerzeichen erreicht { strncpy(&filename[f], &request[i], 1); // Zeichen an Filename anhängen f++; i++; } i=0; // Extensions extrahieren while(strncmp(&filename[i], ".", 1)) // Punkt suchen { i++; } strcpy(ex_extension, &filename[i+1]); // Fileextension extrahieren // Extension zuordnen i=0; format = (char *) 0; while(extensions[i].ext != 0) { if(!strncmp(ex_extension, extensions[i].ext, strlen(ex_extension))) { format = extensions[i].filetype; printf("FORMAT: %s\n", format); break; } i++; } if(format != 0) { printf("OPENING: >%s<\n", filename); printf("EXTENSION: >%s<\n", ex_extension); file_descript=open(filename, O_RDONLY); // Angefordertes File öffnen if(file_descript != -1) { strcpy(request, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"); printf("size> %i\n=========================================================\n\n", strlen(request)); write(sock, request, strlen(request)); while((anzahl=read(file_descript, sendbuffer, sizeof(sendbuffer))) > 0) write(sock, sendbuffer, anzahl); getchar(); close(file_descript); } else printf("Fehler! File konnte nicht geöffnet werden!\n"); } else printf("Falscher MIME-Type!\n"); } else printf("Nur GET-Anfragen werden bearbeitet\n"); }
Jetzt ist mir folgendes aufgefallen:
Über Telnet wird alles übertragen (inkl. Header, anschließend die angeforderte Seite) - Soweit sogut. Das Problem ist tatsächlich nun, dass die Browser nach sehr kurzer (kaum sehbarer Zeit) die Seite verlässt mit der Fehlermeldung "The connection was reset".
Daher habe ich mal das getchar() eingebaut und siehe da, die Page bleibt im Browser, leider eben nur solange mit Enter bestätigt wird.
Was kann ich dagegen tun?
Desweiteren habe ich das Problem, dass ich gerne nachträglich die Art der Anforderung (also HTML, JPG, etc.) einfügen würde. Die Zuweisung klappt schon und in der Variable "format" steht auch der richtige MIME-Type.
Leider habe ich es noch nicht geschafft, diesen in den HTTP-Header einzufügen :\
Hat da jemand ne fixxe Idee?
Gruß
Ähnliche Themen
-
Bild kleiner machen wenn Auflösung kleiner
Von YelloW22 im Forum CSSAntworten: 3Letzter Beitrag: 27.12.10, 11:27 -
Eigener Webserver: Apache Webserver - jBoss
Von janpaet im Forum Hosting & WebserverAntworten: 0Letzter Beitrag: 27.08.07, 20:36 -
kleiner als 1px?
Von vato im Forum PhotoshopAntworten: 21Letzter Beitrag: 03.04.02, 23:21 -
Kleiner Webserver mit PHP
Von Neuk im Forum Hosting & WebserverAntworten: 6Letzter Beitrag: 17.02.02, 14:08



9Danke

Zitieren







Login






