Julian Baumann: C++: TCP Server, Riesenproblem beim Empfang von Daten

Beitrag lesen

Hallo und Grüß Gott,

ich schneie hier herein mit einem (Riesen-) Problem.

Ich komme einfach nicht mehr weiter und hoffe nun hier Hilfe zu bekommen.

Also erstmal ein wenig Code und Erklärung kommen danach:

  
// hier sind die #include  
typedef void (*sighandler_t)(int);  
static sighandler_t  
my_signal(int sig_nr, sighandler_t signalhandler)  
{  
   struct sigaction neu_sig, alt_sig;  
   neu_sig.sa_handler = signalhandler;  
   sigemptyset (&neu_sig.sa_mask);  
   neu_sig.sa_flags = SA_RESTART;  
   if(sigaction (sig_nr, &neu_sig, &alt_sig) < 0) {  
      return SIG_ERR;  
   }  
   return alt_sig.sa_handler;  
}  
  
static void no_zombie (int signr)  
{  
  pid_t pid;  
  int ret;  
  while((pid = waitpid(-1, &ret, WNOHANG)) > 0) {  
   printf ("Child-Server mit pid=%d hat sich beendet\n",pid);  
  }  
  return;  
}  
  
int main (void)  
{  
  int sockfd, connfd, fd, j, n;  
  struct sockaddr_in adresse;  
  const int y = 1;  
  socklen_t adrlaenge = sizeof (struct sockaddr_in);  
  char puffer[1024];  
  pid_t pid;  
  
  if((sockfd = socket (PF_INET, SOCK_STREAM, 0)) < 0) {  
     printf ("Fehler bei socket() ...(%s)\n", strerror(errno));  
     exit (EXIT_FAILURE);  
  }  
  printf ("Socket erfolgreich angelegt\n");  
  adresse.sin_family = AF_INET;  
  adresse.sin_port = htons (PORT_NUMMER);  
  memset (&adresse.sin_addr, 0, sizeof (adresse.sin_addr));  
  setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int));  
  if(bind ( sockfd, (struct sockaddr *)&adresse, sizeof(adresse))) {  
     printf ("Fehler bei bind() ...(%s)\n", strerror(errno));  
     exit (EXIT_FAILURE);  
  }  
  if(listen (sockfd, 5) ) {  
   printf ("Fehler bei listen() ...(%s)\n", strerror(errno));  
   exit (EXIT_FAILURE);  
  }  
  my_signal (SIGCHLD, no_zombie);  
  printf ("Server ist bereit und wartet ...\n");  
  for(;;) {  
     connfd = accept(sockfd, (struct sockaddr *)&adresse, &adrlaenge);  
     if(connfd < 0) {  
        if(errno == EINTR) {  
         continue;  
  } else {  
         printf("Fehler bei accept() (%s)\n",strerror(errno));  
         exit(EXIT_FAILURE);  
        }  
     }  
     printf ("Connection accepted ...\n");  
  
     if ((pid = fork ()) == 0) {  
        close (sockfd);  
 printf("Children started ... \n");  
   printf("Wait for message ... \n");  
  
        j = 0;  
 // // // // // // // //  
        while ((n = read (connfd, &puffer[j], 1)) > 0) { // Diese 3 Zeilen while(){}-Schleife sind mein Problem!  
         j++;  
        }  
 // // // // // // // //  
  
 puffer[j] = '\0';  
        if(n < 0) {  
         printf ("Fehler bei read() ...\n");  
         exit (EXIT_FAILURE);  
        }  
 printf("Message:\n%s\n", puffer);  
  
 close (fd);  
        exit(EXIT_SUCCESS);  
     }  
     close (connfd);  
  }  
  close (sockfd);  
  exit (EXIT_SUCCESS);  
}  

Das Programm wird bei mir absolut Fehlerfrei erstellt.
Das spielt sich bei mir auf der Konsole ab:

Socket erfolgreich angelegt
Server ist bereit und wartet ...
Connection accepted ...
Children started ...
Wait for message ...
/* [Hier passiert dann gar nichts mehr, das heisst der Client (z.B. Firefox) sendet aber der Server gibt momentan nichts aus.
 Der Client hat fertig übertragen und wartet auf Antwort
 Der Server wartet meines erachtens immer noch auf Nachricht obwohl der Client schon fertig ist
 Beendet man den Client dann gibt der Server das aus was schon lange auf dem Bildschirm zu sehen sein sollte.] */
Message:
GET / HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.8.1.4) Gecko/20070603 Fedora/2.0.0.4-2.fc7 Firefox/2.0.0.4
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cache-Control: max-age=0

Child-Server mit pid=9797 hat sich beendet

Warum ist das so?
Wie kann ich Abhilfe schaffen?
Meine Quelle ist dieses tutorial.
Habe auch schon andere Tutorials ausprobiert aber die ähneln sich eh ziemlich.

Julian Baumann