IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

probleme avec l'envoi d'un fichier avec les socket


Sujet :

Réseau C

  1. #1
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut probleme avec l'envoi d'un fichier avec les socket
    salut les amis
    je viens de commencer avec les socket et je veux savoir comment transferer un fichier (un gif dans mon ex)
    cote serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <winsock2.h>
    #define TAILLE_MAX 1024
     
    int main() {
     
      WSADATA WSAData;
      WSAStartup(MAKEWORD(2,0), &WSAData);
      struct sockaddr_in addr1,addr2 ;
      char  chaine[TAILLE_MAX] , T[TAILLE_MAX];
     
      FILE *fichier = fopen("server.gif","r");
      if(fichier == NULL){
            printf("Error avec le fichier\n");
            getch();
            exit(1);
      }
     
      int Id1 = socket(AF_INET,SOCK_STREAM,0) ;
     
      addr1.sin_family = AF_INET ;
      addr1.sin_port = htons(1500) ;
      addr1.sin_addr.s_addr = htonl(INADDR_ANY) ;//inet_addr("127.0.0.1") ;
     
      if( bind( Id1,(struct sockaddr *)&addr1,sizeof(addr1) ) == -1 ){
             printf("Bind Error\n") ;
             getch();
             exit(1);
      }
     
      listen(Id1,10);
      printf("En attente de connexion...\n");
      int len1 = sizeof addr2 ;
      int Id2 = accept( Id1 , (struct sockaddr *) (&addr2) , &len1 )  ;
     
      printf("Machine connected !!\nIP : %s\tID : %d\n",inet_ntoa(addr2.sin_addr),Id2);
     
      while(fgets(chaine, TAILLE_MAX, fichier) != NULL){
            printf("%d Octets send\n",send(Id2 , chaine , strlen(chaine) , 0));
      }
     
      close(Id1);
      close(Id1);
      fclose(fichier);
      WSACleanup();
      getch();
    }
    cote client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <winsock2.h>
    #define TAILLE_MAX 1024
     
    int main() {
      WSADATA WSAData;
      WSAStartup(MAKEWORD(2,0), &WSAData);
      FILE *fichier = NULL ;
     
      struct sockaddr_in addr1,addr2 ;
      int n;
      char T[TAILLE_MAX];
      int ID1 = socket(AF_INET,SOCK_STREAM,0) ;
     
      addr1.sin_family = AF_INET ;
      addr1.sin_port = htons(1500) ;
      addr1.sin_addr.s_addr = inet_addr("127.0.0.1") ;
     
      if( connect( ID1,(struct sockaddr *)&addr1,sizeof addr1 ) < 0 ){
             printf("Connect Error\n") ;
             getch();
             exit(1);
      }
      printf("Connect to server !!\n");
     
      if( (fichier=fopen("client.gif","w")) == NULL ){
             printf("Error avec le fichier\n");
             getch();
             exit(1);
      }
     
      while( (n=recv( ID1 , T , TAILLE_MAX-1 , 0)) > 0 ){
            T[n]='\0' ;
            fputs(T, fichier);
            printf("%d octets recv\n",n);
      }
     
      close(ID1);
      fclose(fichier);
      WSACleanup();
      getch();
    }
    voila le resultat
    du serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    En attente de connexion...
    Machine connected !!
    IP : 127.0.0.1  ID : 140
    7 Octets send
    51 Octets send
    93 Octets send
    18 Octets send
    153 Octets send
    19 Octets send
    51 Octets send
    93 Octets send
    18 Octets send
    (7 +51 +93 +18 +153 +19 +51 +93 +18 = 503 )
    du client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Connect to server !!
    503 octets recv
    mais en resultat le fichier client.gif n'est pas vraiment une image
    sa taille est 508 octets alors que la vrai image a 870 octets
    et parfois j'obtien en resulat 0 octets
    et d'autre fois
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Connect to server !!
    485 octets recv
    18 octets recv
    alors quelle est le probleme ?

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Une image gif est un fichier binaire; il faut donc lire ce fichier de manière binaire et l'envoyer de manière binaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     FILE *fichier = fopen("server.gif","r");
    devient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     FILE *fichier = fopen("server.gif","rb");
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while(fgets(chaine, TAILLE_MAX, fichier) != NULL){
            printf("%d Octets send\n",send(Id2 , chaine , strlen(chaine) , 0));
      }
    Est à remplacer par un lecture via fread, genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    do {
        size_t n = fread(buf, 1, 128, fichier);
        if(n>0) {
            int sd = send(Id2, buf, n, 0);
            printf("%d octects sent\n", sd);
        } else {
            break;
        }
    } while(1);
    voire via fgetc.

    même chose côté client : ouvrir en mode écriture binaire "wb" et utiliser fwrite.

  3. #3
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    j'ai ajouter les "wb" et "rb"
    et j'ai remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      while( ( n = fread(chaine, 1, 128, fichier) ) > 0){
            printf("%d Octets send\n",send(Id2 , chaine , n , 0));
      }
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      while( (n=recv( ID1 , T , TAILLE_MAX-1 , 0)) > 0 ){
            T[n]='\0' ;
            fwrite(T, 1, 128, fichier);
            printf("%d octets recv\n",n);
      }
    toujours le meme probleme

  4. #4
    Invité(e)
    Invité(e)
    Par défaut
    La valeur 128 était juste donnée à titre d'exemple...

    Citation Envoyé par yous18 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      while( (n=recv( ID1 , T , TAILLE_MAX-1 , 0)) > 0 ){
            T[n]='\0' ;
            fwrite(T, 1, 128, fichier);
            printf("%d octets recv\n",n);
      }
    toujours le meme probleme
    Problème : on lit 1024 octect depuis la socket, mais on en écrit que 128 dans le fichier... donc il en manque.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      /* la seule contrainte ici porte sur T : sa taille doit au moins être de 128 char. */
    while( (n=recv( ID1 , T , 128 , 0)) > 0 ){
            fwrite(T, 1, 128, fichier);
            printf("%d octets recv\n",n);
      }
    EDIT : bêtise dans le code (qui ne devrait pas avoir d'effet sur la tête de l'image néanmoins)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      /* la seule contrainte ici porte sur T : sa taille doit au moins être de 128 char. */
    while( (n=recv( ID1 , T , 128 , 0)) > 0 ){
            fwrite(T, 1, n, fichier);
            printf("%d octets recv\n",n);
      }
    Dernière modification par Invité(e) ; 05/02/2009 à 07h12.

  5. #5
    Membre du Club
    Inscrit en
    Août 2007
    Messages
    260
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 260
    Points : 43
    Points
    43
    Par défaut
    merci t'a raison ça marche mais juste en local
    j'ai essayé d'envoyer l'image a un ami mais elle a etait corrompu
    on voit l'image mais elle est deformé !!!!

  6. #6
    Invité(e)
    Invité(e)
    Par défaut
    Citation Envoyé par yous18 Voir le message
    merci t'a raison ça marche mais juste en local
    j'ai essayé d'envoyer l'image a un ami mais elle a etait corrompu
    on voit l'image mais elle est deformé !!!!
    Essayez de commencer avec des fichiers dont le contenu est connu par exemple : un fichier texte contenant une série de 100 'a', une de 100 'b'... l'effet de la transmission sur les données sera tout de suite visible.

    je ne suis pas expert en réseau, mais je me demande s'il n'y a pas un risque de voir arriver les paquets TCP dans n'importe quel ordre... dans ce cas, il faudra prévoir de les identifier.

  7. #7
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par mabu Voir le message
    je ne suis pas expert en réseau, mais je me demande s'il n'y a pas un risque de voir arriver les paquets TCP dans n'importe quel ordre... dans ce cas, il faudra prévoir de les identifier.
    NON, IP et TCP garantissent que les paquets arrivent dans l'ordre de leur émission (je ne sais plus si la garantie d'ordonnancement se fait au niveau de IP ou de TCP).

    Par contre, ce qui peut arriver :
    • 1 emission de 90 octets ==> 3 réceptions de 20, 30 et 40 octets
    • 3 emission de 30 octets ==> 1 réception de 90 octets

    Le nombre d'emissions et de réceptions peut ne pas être le même et donc en général, sur des flux où l'on envoie un fichier, comme ici, la première chose envoyée, c'est la longueur du fichier afin que le récepteur sache quand c'est la fin du fichier.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  8. #8
    Membre éclairé Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Points : 862
    Points
    862
    Par défaut
    Citation Envoyé par ram-0000
    NON, IP et TCP garantissent que les paquets arrivent dans l'ordre de leur émission (je ne sais plus si la garantie d'ordonnancement se fait au niveau de IP ou de TCP).
    Si je ne me trompe pas:
    - La couche IP garantit de reconstituer un paquet fragmenté, notamment grâce aux champs 'Identification' et 'Posifion Fragment'
    - La couche TCP permet entre-autres de remettre dans l'ordre de leur émission les paquets réceptionnés, notamment grâce au champ 'Numéro de Séquence'.

  9. #9
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    je voudrais pas faire mon rabat-joie, mais envoyer une image binaire devrait se faire via un buffer de unsigned char, où la taille est passée à part...

    Envoyer une image en binaire tel quel est courir à sa perte...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [WS 2003] Envoi d'un fichier avec Net send
    Par dari68 dans le forum Windows Serveur
    Réponses: 3
    Dernier message: 30/10/2013, 15h40
  2. [1.x] envoi d'un fichier avec des paramètres dans un formulaire
    Par safa.nasich dans le forum Symfony
    Réponses: 2
    Dernier message: 15/07/2011, 11h17
  3. échec d'envoi de gros fichier avec sp_send_dbmail
    Par ulmeen dans le forum Développement
    Réponses: 4
    Dernier message: 02/07/2010, 16h52
  4. Probleme de retour chariot (Traitement du fichier avec AWK)
    Par abb.wafa dans le forum Shell et commandes GNU
    Réponses: 1
    Dernier message: 21/01/2010, 15h05
  5. Ouvrier un fichier avec macro depuis un autre fichier avec macro
    Par Jeanvaljean44 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 21/11/2008, 11h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo