2016-04-20 5 views
0

Ich schreibe mein erstes Client/Server-Programm. Der Client sendet den Namen einer Datei und der Server sollte die Datei senden (falls vorhanden). Server:Empfange keine Daten und recv() gibt 0 zurück

while(1) 
    { 
     client_sock_fd = accept(listening_sock_fd, (struct sockaddr*)NULL, NULL); 
     if (client_sock_fd == -1) 
     { 
      fprintf(stderr, "ERROR: accept()\n"); 
      continue; 
     } 

     if (!fork()) 
     { 
      close(listening_sock_fd); 

      if ((numbytes = recv(client_sock_fd, buff, 1023, 0)) == -1){ 
       fprintf(stderr, "ERROR: recv()\n"); 
       return EXIT_FAILURE; 
      } 

      buff[numbytes] = '\0'; 

      FILE *f = fopen(buff, "r"); 

      if (f == NULL){ 
       if ((send(client_sock_fd, "FAIL", 4, 0)) == -1) 
       { 
        fprintf(stderr, "ERROR: send()\n"); 
       } 
      }else { 

       if ((send(client_sock_fd, "OK", 2, 0)) == -1) 
       { 
        fprintf(stderr, "ERROR: send()\n"); 
       } 

       char * buffer = 0; 
       long length; 


       fseek (f, 0, SEEK_END); 
       length = ftell (f); 
       fseek (f, 0, SEEK_SET); 
       if((buffer = malloc (length)) == NULL){ 
        fprintf(stderr, "ERROR: malloc()\n"); 
        exit(1); 
       } 
       if (buffer) 
       { 
        fread (buffer, 1, length, f); 
       } 
       fclose (f); 


       char str[1024]; 
       sprintf(str, "%d", (int)strlen(buffer)); 
       if ((send(client_sock_fd, str, strlen(str), 0)) == -1) 
       { 
        fprintf(stderr, "ERROR: send()\n"); 
       } 

       int s = sendall(client_sock_fd, buffer, strlen(buffer)); 
       if (s == -1){ 
        fprintf(stderr, "ERROR: send()\n"); 
        free(buffer); 
        exit(1); 
       } 


       free(buffer); 
      } 

      close(client_sock_fd); 
      exit(0); 
     } 
     close(client_sock_fd); 
    } 

int sendall(int s, char *buf, int len) 
{ 
    int total = 0; 
    int bytesleft = len; 
    int n; 

    while(total < len) { 
     n = send(s, buf+total, bytesleft, 0); 
     if (n == -1) { break; } 
     total += n; 
     bytesleft -= n; 
    } 

    return n==-1?-1:0; 
} 

Auftraggeber:

if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ 
     fprintf(stderr, "ERROR: chyba pri socket()\n"); 
     return EXIT_FAILURE; 
    } 

    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_port = htons(args.port_num); 

    if ((prlHst = gethostbyname(argv[args.host_name])) == NULL){ 
     fprintf(stderr, "ERROR: gethostbyname()\n"); 
     return EXIT_FAILURE; 
    } 

    memcpy(&serv_addr.sin_addr, prlHst->h_addr_list[0], prlHst->h_length); 

    if (connect(sock_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){ 
     fprintf(stderr, "ERROR: connect()\n"); 
     return EXIT_FAILURE; 

if ((send(sock_fd, argv[args.file], strlen(argv[args.file]), 0)) == -1){ 
     fprintf(stderr, "ERROR: send()\n"); 
     return EXIT_FAILURE; 
    } 

    if ((numbytes = recv(sock_fd, buff, 1023, 0)) == -1){ 
     fprintf(stderr, "ERROR: recv()\n"); 
     return EXIT_FAILURE; 
    } 

    buff[numbytes] = '\0'; 

    FILE *fp = fopen(argv[args.file], "w"); 
    if (fp == NULL){ 
     fprintf(stderr, "ERROR: fopen()\n"); 
     return EXIT_FAILURE; 
    } 
    if (!strcmp(buff, "OK")){ 
     if ((numbytes = recv(sock_fd, buff, 1023, 0)) == -1){ 
      fprintf(stderr, "ERROR: recv()\n"); 
      return EXIT_FAILURE; 
     } 

     char *pEnd; 
     long int dataToRead = strtol(buff, &pEnd, 10); 
     long int readData = 0; 

     fprintf(stderr, "data to read %lu\n", dataToRead); 

     while (readData < dataToRead) { 
      unsigned char buffer [4096] = {0}; 
      int nbuffer; 
      for (nbuffer = 0; nbuffer < 4096;) { 

       int len = recv(sock_fd, buffer, 4096, 0); 
       if (len == -1){ 
        fprintf(stderr, "ERROR: recv()\n"); 
        return EXIT_FAILURE; 
       } 
       /* FIXME: Error checking */ 

       nbuffer += len; 
       readData += len; 

      } 

      fwrite(buffer, sizeof(unsigned char), nbuffer, fp); 
     } 

Alles funktioniert, bis die while-Schleife in Client in Ordnung. recv gibt immer 0 zurück. Warum das? Was ist falsch in meinem Code? Ich habe versucht, etwas in die gewünschte Datei zu schreiben mit einer send senden und es wurde empfangen. Auch habe ich dataToRead Variable überprüft und es ist in Ordnung, enthält den erwarteten Wert. Danke für die Antworten!

+0

Rückgabewert von 0 zeigt normalerweise an, dass der Socket geschlossen wurde. Wo initialisierst du den Socket im Client? Konnte es in Ihrem Codebeispiel nicht sehen. –

+0

OK, Sie finden die Datei, erhalten ihre Länge, ordnen einen "Längen" -Speicher für die ganze Datei zu, (im Allgemeinen keine gute Idee), und dann ... unausweichlich, verwenden Sie strlen (Puffer) für die Folowing Code: ((Sie wissen bereits die Länge, also warum Zeit verschwenden auf Strlen() Anrufe und machen Sie Code nicht in der Lage, Daten mit Null-Bytes darin zu behandeln? –

+0

@ JonathonOgden Ich habe die Initialisierung, @jxh Ich habe es mit einer Datei versucht mit 5 Zeichen, also hatte ich in 'dataToRead' den Wert' 6'. –

Antwort

0

Alles funktioniert gut, bis die While-Schleife im Client. recv gibt immer 0 zurück. Warum ist das?

Dies bedeutet, dass der Peer die Verbindung geschlossen hat.

Was ist falsch in meinem Code?

Sie erkennen den Zustand nicht, schließen den Socket und hören auf, davon zu lesen. Dies ist, was Sie tun müssen, wenn recv() 0 zurückgibt, oder tatsächlich, wenn es -1 mit errno gleich allem außer EAGAIN/EWOULDBLOCK zurückgibt.

Ich habe versucht, etwas auf die gesuchte Datei mit einem senden zu senden und es wurde empfangen. Außerdem habe ich die Variable dataToRead überprüft und es ist in Ordnung, sie enthält den erwarteten Wert.

Ich verstehe nicht, was das damit zu tun hat.

Ihre Kopierschleifen sind lächerlich übermäßig komplex. Die kanonische Weise Bytes von einer Buchse in eine Datei bis zum Ende des Stroms an der Buchse zu übertragen, ist wie folgt:

while ((count = recv(socket, buffer, sizeof buffer)) > 0) 
{ 
    write(file, buffer, count); 
} 

und umgekehrt für den Bytes aus einer Datei an einen Socket übertragen:

while ((count = read(file, buffer, sizeof buffer)) > 0) 
{ 
    send(socket, buffer, count); 
}