2010-01-20 11 views
0

Ce code envoie et recv fichier s txt parfaitement, mais ne peut pas le faire à d'autres formats comme .exe ou .img. S'il vous plaît aidez-moi avec ceux-ci comme j'ai besoin d'utiliser htonl ou htons ?? Jetez un oeil !!Recv() fonctions indicateur pour prendre le tampon while dans une chaîne [Windows C]

fonction recv côté est le serveur ici ::

if (socket_type != SOCK_DGRAM) 
     { 

       fi = fopen (final,"wb"); 
       retval = recv(msgsock, recv_buf, strlen(recv_buf), 0); 
       /*recv_buf[retval] = '\0'; 
       fprintf (fi,"%s",recv_buf);*/ 

       int i; 
       i=atoi(recv_buf); 
       char *q; 
       q=(char *)malloc(i*sizeof(char)); 
       retval = recv(msgsock, q, strlen(q), 0); 
       //printf ("%s",q); 
       fwrite(q,i,1,fi); 
       fclose(fi); 

     } 
     else 
     { 
      retval = recvfrom(msgsock,recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&from, &fromlen); 
      printf("Server: Received datagram from %s\n", inet_ntoa(from.sin_addr)); 
      printf ("SOCK_DGRAM"); 
     } 

     if (retval == SOCKET_ERROR) 
     { 
      fprintf(stderr,"Server: recv() failed: error %d\n", WSAGetLastError()); 
      closesocket(msgsock); 
      //continue; 
     } 
     else 
      printf("Server: recv() is OK.\n"); 

     if (retval == 0) 
     { 
      printf("Server: Client closed connection.\n"); 
      closesocket(msgsock); 
       //continue; 
     } 
     printf("Server: Received %d bytes, data from client\n", retval); 

The client side sending function ::: 

void send_command() 
{ 
    int bytesent; 
    FILE *file_out; 
    //file_out = fopen(file_path,"rb"); 
    char str_all[100000];//flag [30]="end"; 

    ///////////////////////getsize////////////// 
    char fsize[5]; 
    int filesize; 
    file_out = fopen(file_path, "rb"); 
    fseek(file_out, 0, SEEK_END); 
    filesize = ftell(file_out); 
    rewind (file_out); 
    itoa (filesize,fsize,10); 
    ///////////////////////////////////////////// 
    send (ConnectSocket, fsize, strlen (fsize), 0); 

    char *r = (char *)malloc (filesize * sizeof(char)); 

    fread(r,filesize,1,file_out); 
    bytesent = send(ConnectSocket, r, strlen(r), 0); 
    printf("\nClient: Bytes sent: %ld\n", bytesent); 
    fclose (file_out); 

    /*while (fscanf(file_out,"%s",&str_all) != EOF) 
    { 
     bytesent = send(ConnectSocket, str_all, strlen(str_all), 0); 
     printf("\nClient: Bytes sent: %ld\n", bytesent); 
     //Sleep(500); 
    }*/ 

    /*printf("%s",flag); 
    send(ConnectSocket, flag, strlen(flag), 0);*/ 
    WSACleanup(); 
    //return 0; 
    } 

Répondre

2

OK, il existe plusieurs problèmes avec votre programme.

  • Vous transférez des données binaires. Le récepteur va seulement voir une séquence d'octets. Le récepteur n'a aucun moyen de connaître la fin des données, car toutes les valeurs possibles de char sont des valeurs de données légales. Si vous envoyez des données textuelles, vous pouvez dire qu'un 0 indique la fin des données, mais vous ne pouvez plus le faire. Donc, vous devez décider d'un "protocole" entre le serveur et le client — le plus simple est que le serveur envoie la longueur des données dans les 4 premiers octets (lire ntonl() et ntohl() pour savoir comment faire cela portably). Ensuite, le récepteur saura exactement combien d'octets il doit lire.
  • Vous déclarez le tampon récepteur comme char *recv_buf et de la même manière pour recv_buf1. Vous n'allouez aucun stockage pour aucun des deux pointeurs, donc ils ne pointent vers aucun endroit utile. Ensuite, votre appel recv est: recv(msgsock, recv_buf, sizeof(recv_buf), 0); Cela a également des problèmes. Le premier est celui mentionné ci-dessus: vous n'avez pas de stockage pour recv_buf. La seconde est que, après allouer le stockage pour recv_buf, vous prenez la taille d'un pointeur char au lieu de la longueur du tampon recv points à. Un moyen facile de résoudre les deux problèmes serait de déclarer recv_buf comme: char recv_buf[SIZE];, puis d'utiliser sizeof recv_buf dans l'appel recv().

Je n'ai pas regardé le reste de votre code. Vous avez probablement besoin d'une bonne introduction à la programmation C et réseau.

+0

L'allocation est un problème que j'ai trouvé mais je suis vraiment noob à ce sujet et l'apprends comme 2 semaines maintenant. Htons est une solution à laquelle je pensais mais que je ne peux pas appliquer. Merci d'avoir répondu!! –

+0

Si allocation est un problème, vous pouvez utiliser un tableau comme je l'ai dit, mais à long terme, vous devriez apprendre des pointeurs et malloc et amis en C. Pour le réseautage, il existe de nombreux bons tutoriels en ligne, ou vous pouvez lire les livres de Stevens . –

1

Je pense que vous confondez nulle terminaison d'une chaîne C avec la fin d'un paquet envoyé sur un socket. Il n'y a pas de "terminaison" d'un paquet, c'est juste une chaîne d'octets. Les zéros sont complètement légaux, et vous passez (et recevez) la longueur explicitement. Vous n'avez certainement pas besoin d'utiliser les fonctions hors bande pour recevoir plusieurs paquets. Pouvez-vous être plus précis sur ce que vous demandez?

+0

Je veux envoyer un fichier comme .mp3 ou n'importe quel format et le recive et l'enregistre comme .mp3. Donc, les deux parties doivent envoyer et recv simultanément! Lorsque j'envoie un fichier texte, le serveur ne reçoit que la longueur avant ESPACE ou ENTRÉE (/ n). J'ai donc besoin d'envoyer un fichier tel quel. Le problème est du côté serveur car il ne peut pas recevoir simultanément. –

+2

Je ne suis pas. Je pense que vous devez revenir en arrière et lire quelques tutoriels sur la programmation de socket. Stevens Unix Network Programming est le livre classique, mais il y a beaucoup de contenu web disponible. –