ah3n0bar6us
Goto Top

Einfacher Webserver in C mit select()

Hallo liebe Fachleute,

mein Kommilitone und ich sind ziemlich am verzweifeln, da unsere letzte Aufgabe im Studium eine "einfache" Webserverprogrammierung ist. Wir sollen das aufbauen auf ein anderes Programm (was auch schon aufbauen auf ein anderes war) durchführen. Leider hatten wir selbst da schon unsere Probleme und haben es gerade noch so jeweils zu einen Punkt gebracht. Das Verständnis ist grob da, aber die Umsetzung wie immer schwer. Das zur Einleitung =)

Unsere letzte Aufgabe war ein Server Client Chat Script. Der Server ist meiner Meinung nach gut gelungen, nur gab es da Probleme bei dem Anzeigen der erhaltenen Nachrichten bei allen anderen Clients (und auch beim Sendenden Client). Jedoch denke ich den Server, s.u., kann man gut für die Umsetzung nutzen.

ich weiss, dass wir bei der Umsetzung eines rudimentären IIS eine get Anfrage erhalten müssen. Das sollen wir natürlich mit einem Browser testen. Dabei soll der Pfad und und der Port angegeben werden. Das ist ja erstmal nicht so wild.
Dann muss diese Anfrage des Pfades getrennt werden, dass es nicht höher als zum vorgesehenen Root Verzeichnis geht. Mhh.. prüfe ich jetzt den String auf enthaltene bekannte Verzeichnisnamen? Oder nehme ich den String einfach als Unterverzeichnis hin?

Dann die eigentliche Rückgabe mit POST.
HTTP/1.0 200 OK. Aber mit welchem Befehl? mit send() ? Und worauf bezieht sich das? Dass das übergebene Verzeichnis http (z.B. iis /http/ 8080) vorhanden ist?

ich sitze sonst immer Tage an sehr unbefriedigende Ergebnisse und habe gehofft etwas Hilfe zu bekommen. Ich würde mich sehr freuen.


#define SPEICHER 1024
#include <stdbool.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <netdb.h>
#include <sys/select.h>   

int main(){
  int s, s2, fdmax, textSize, yes = 1;                          
  fd_set active_fd_set, read_fd_set;
  struct sockaddr_in local, clientsocket; 
  socklen_t addr_size;     
  char *str = malloc(SPEICHER);         // Speicher für die Nachricht

  // Für chatserver den set des aktiven Socket initialisieren
  FD_ZERO (&active_fd_set);
  FD_ZERO (&read_fd_set);

  // Socket erstellen und Fehlerbehandlung
  if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("Socketerrror");  
    return EXIT_FAILURE;
  }

  if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
    perror("Setsockopterror");  
    exit(1);
  }

  local.sin_family = AF_INET;
  local.sin_port = htons(7891);
  local.sin_addr.s_addr = htonl(INADDR_ANY);
  memset(&(local.sin_zero), '\0', sizeof(local.sin_zero));   

  if(bind(s, (struct sockaddr *) &local, sizeof(local)) == -1){
    perror("Binderror");  
    return EXIT_FAILURE;
  }

  if(listen(s,8)==-1) {
    perror("Listeningerror");  
    return EXIT_FAILURE;
  }

  FD_SET (s, &active_fd_set);
  fdmax = s;

  printf("%s\n", "Server gestartet." );  

  // unsere Dauerschleife
  for(;;){
    // chatserver blocken, wenn eine Nachricht kommt
    read_fd_set = active_fd_set;
    if (select (fdmax+1, &read_fd_set, NULL, NULL, NULL) == -1){
      perror ("Selecterror");  
      return EXIT_FAILURE;
    }

    // Durchlaufe die Verbindungen
    for (int i = 0; i <= fdmax; i++){
      // Prüfe, ob jmd verbunden ist
      if(FD_ISSET(i, &read_fd_set)){
        if (i == s) {
          addr_size = sizeof clientsocket;
          if ((s2 = accept(s, (struct sockaddr *) &clientsocket, &addr_size)) == -1){
            perror("Accepterror");  
          } else {
            // Client hinzufügen
            FD_SET(s2,&active_fd_set);
            // Maximale Verbindungen beachten
            if(s2 > fdmax)
              fdmax = s2;
            printf("Neue Verbindung %s auf socket %d\n", inet_ntoa(clientsocket.sin_addr), s2);  
          }
        } else {
          if ((textSize = recv(i,str, SPEICHER,0)) <= 0){
            close(i);                   // Verbindung schliessen
            FD_CLR(i,&active_fd_set);   // Vom Server trennen
          }else{
            // Text empfangen
            for(int j = 0; j <= fdmax; j++){
              if (FD_ISSET(j,&active_fd_set)){
                printf("Empfangener Text: %s\n", str);  
                /* Webseite zurückgeben */
                
                
              }
            }
          }
        }
      }
    }
  }
  close(s);
  free(str);

  return EXIT_SUCCESS;
}

Beste Grüße

Ah3

Content-Key: 309554

Url: https://administrator.de/contentid/309554

Printed on: May 4, 2024 at 01:05 o'clock

Member: Dirmhirn
Dirmhirn Jul 12, 2016 updated at 13:01:36 (UTC)
Goto Top
Hi,

was studiert ihr denn?

für "Vorlagen" kannst du mal hier suchen:
https://github.com/explore

für konkrete programmiertechn. Fragen:
http://stackoverflow.com/

sg Dirm