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

 C Discussion :

Petit client serveur avec tubes nommés.


Sujet :

C

  1. #1
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 23
    Par défaut Petit client serveur avec tubes nommés.
    Salut a tous,

    Je suis en train de programmer une petite application client serveur avec des tubes nommés et je voulais savoir s'il y a possibilité d'envoyer un fichier texte au serveur.

    J'ai essayé ce bout de code mais il ne marche pas:

    code client:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        FILE * fichier = fopen( "test", "r" );
        ssize_t nbOctetsEcris = write( tube, fichier, sizeof( fichier ) );
    code serveur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        FILE * fichierRecu = NULL;
        ssize_t nbOctetsLus = read( tube, fichierRecu, sizeof( fichierRecu ) );
    Bien sur j'ai fait toutes les opérations préalables telles que créer le tube, ouvrir le tube...etc.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 474
    Par défaut
    Bonsoir,

    Citation Envoyé par maximus15 Voir le message
    Je voulais savoir s'il y a possibilité d'envoyer un fichier texte au serveur. J'ai essayé ce bout de code mais il ne marche pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        FILE * fichier = fopen( "test", "r" );
        ssize_t nbOctetsEcris = write( tube, fichier, sizeof( fichier ) );
    code serveur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        FILE * fichierRecu = NULL;
        ssize_t nbOctetsLus = read( tube, fichierRecu, sizeof( fichierRecu ) );
    Ah non, ça, en effet, ça ne risque pas de marcher ! :-)

    Un fichier se gère à peu de choses près comme un tube : il faut lire ou écrire dedans. Donc, en gros, tu déclares un buffer de taille fixe, tu fais une boucle, tu lis n octets de ton fichier dans ton buffer, tu écris ces n octets dans ton tube, et tu recommences jusqu'à la fin.

  3. #3
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 23
    Par défaut
    Salut Obsidian,

    Merci beaucoup pour ta réponse rapide et claire.

    Vu que mon code ne marchait pas, ce que j'ai fait est de me déclarer une structure du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct _fichier {
        char * nom;
        char ** contenu;
    };
     
    typedef struct _fichier Fichier;
    ensuite je me suis déclaré une autre structure qui représente une requête:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct _requete {
        char * usager; /* Représente l'usager qui va se connecter au serveur */
        Fichier * leFichier;
    }
     
    typedef _requete Requete;
    dans mon code client je crée la requête a envoyer au serveur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Requete * req = malloc( sizeof( Requete ) );
    char nomUsager [256];
    printf( "Entrez le nom de l'usager: " );
    scanf( "%s", nomUsager );
     
    req->usager = nomUsager;
     
    ssize_t nbOctetsEcris = write( tube, req, sizeof( req ) );
    la lecture au niveau du serveur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Requete * req = malloc( sizeof( Requete ) );
    req->usager = malloc( sizeof( char ) * 256 );
     
    ssize_t nbOctetsLus = read( tube, req, sizeof( req ) );
    Pour l'instant le deuxieme champ de la structure req n'est pas important.

    Ce qui m'intrigue c'est que quand j'essaie d'afficher le nom de l'usager au niveau du serveur, ca ne marche pas, il n'y a même pas d'erreur de segmentation et le problème c'est que quand j'affiche le nombre d'octets ecris et lus c'est la meme chose.

    J'ai rajoute un entier dans la structure requête et quand je l'affiche au serveur, ca marche...incroyable.

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 474
    Par défaut
    Ce qui m'intrigue c'est que quand j'essaie d'afficher le nom de l'usager au niveau du serveur, ca ne marche pas, il n'y a même pas d'erreur de segmentation et le problème c'est que quand j'affiche le nombre d'octets ecris et lus c'est la meme chose.
    C'est normal. Quand tu procèdes de cette façon, tu envoies le contenu de ta structure « Requete ». Or, celle-ci contient un pointeur vers ton buffer, pas le buffer lui-même. Ce pointeur a probablement été transmis comme il faut, mais du côté serveur, bien sûr, il ne correspond à rien.

    Le fait qu'il n'y ait pas de segfault n'est pas probant. L'adresse virtuelle qu'il contient tombe sans doute aussi dans l'espace mémoire de ton serveur, ce qui est d'autant plus probable que ce processus est sûrement plus gros que son client.

    D'ailleurs, il y a d'autres erreurs. Quand tu écris :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    ssize_t nbOctetsEcris = write( tube, req, sizeof( req ) );

    … c'est la taille du pointeur req que tu calcules, soit 4 octets sur un PC 32 bits. Tu ne transmets donc que les 4 premiers octets de ta structure. Ça tombe bien, c'est exactement l'emplacement et la taille du pointeur « usager » qu'elle contient. C'est « sizeof( Requete ) » qu'il aurait fallu écrire, comme tu l'as fait pour ton malloc().

    J'ai rajoute un entier dans la structure requête et quand je l'affiche au serveur, ca marche...incroyable.
    Si tu as ajouté cet entier en début de structure, c'est normal aussi : un entier ordinaire sur un PC 32 bits fait 4 octets aussi, soit la taille d'un pointeur.

  5. #5
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 23
    Par défaut
    Salut Obsidian,

    Merci encore pour ta réponse.

    Maintenant si je veux transmettre ma structure avec les données qu'elle contient, je procède comment.

    Faut-il que je me déclare une structure statique au lieu d'un pointeur, mais de toute façon il me faut un pointeur sur la structure a cause du write et du read.

    Merci.

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 474
    Par défaut
    Citation Envoyé par maximus15 Voir le message
    Maintenant si je veux transmettre ma structure avec les données qu'elle contient, je procède comment.
    C'est bien le problème, justement : ta structure ne contient pas ce que tu veux envoyer. Ta structure contient un pointeur vers un buffer qui se trouve en dehors. Si tu veux envoyer le contenu de ce buffer, il faut l'émettre de la même façon.

    Ou alors, tu déclares directement ton tableau au sein de ta structure. Là, il en fera officiellement partie, et la taille de cette dernière sera calculée en conséquence.

    Faut-il que je me déclare une structure statique au lieu d'un pointeur, mais de toute façon il me faut un pointeur sur la structure a cause du write et du read.
    Un pointeur ne contient que l'adresse en mémoire de quelque chose. Tu peux tout-à-fait passer cette adresse directement avec « & ».

  7. #7
    Membre averti
    Inscrit en
    Mars 2009
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 23
    Par défaut
    Salut Obsidian,

    Merci encore pour tes réponses.

    Finalement, j'ai déclaré mes tableaux a l'intérieur de ma structure et ca a marché.

    Merci encore.

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

Discussions similaires

  1. Petit client serveur avec tubes nommés.
    Par maximus15 dans le forum Linux
    Réponses: 2
    Dernier message: 08/02/2010, 18h53
  2. Réponses: 2
    Dernier message: 22/02/2006, 17h41
  3. Réponses: 1
    Dernier message: 01/02/2006, 17h48
  4. Client-serveur avec VB6 inside
    Par kremvax dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 28/11/2005, 13h08
  5. [SOCKET] connexion client serveur avec applet
    Par kaiser2003 dans le forum Applets
    Réponses: 2
    Dernier message: 06/10/2004, 22h32

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