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 :

Socket Linux - serveur d'application


Sujet :

Réseau C

  1. #1
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Février 2012
    Messages : 21
    Par défaut Socket Linux - serveur d'application
    Bonjour,
    Dans le cadre d'une formation, je dois réaliser un petit serveur d'application qui va me permettre de faire 2 choses : déterminer si le nombre envoyé par le client est un nombre premier, ou bien de calculer l'aire et la circonférence d'un cercle avec le rayon envoyé par le client.

    Côté "algorithmique", j'ai déjà les calculs de faits :
    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
     
    pour le calcul de nombre premier ou non
    int main (void)
    {
      int i, nb, test;
      test  = 0;
      printf ("Entrez un nombre entier : ");
      if (scanf ("%d", &nb) != 1)
        return -1;
     
      for (i = 2; i < nb; i++, compter++)
        if (nb % i == 0)
          test = 1;
      if (!test)
        printf ("%d nombre premier \n", nb);
      else
        printf ("%d n'est pas nombre premier\n", nb);
      return 0;
    }
    J'ai pu créer un serveur et un client qui se voient et discutent (testé en envoyant une chaîne de caractères depuis le client qu'on récupère côté serveur avant de la renvoyer sur le client). Maintenant, j'aimerais pouvoir envoyer une opérande (p pour premier et c pour cercle).
    Pour cela, je pensais passer par une structure :

    fichier request.h
    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
     
    #ifndef REQUEST_H_
    #define REQUEST_H_
     
     
    //structure requete
     
    struct Request {
    	int operande1;
    	char operateur;
      };
    	typedef struct Request Request;
     
     
    // structure reponse
    struct Response {
    	float result;
     	};
    typedef struct Response Response;
     
    #endif /* REQUEST_H_ */
    Mon client (la partie application en elle-même, la connexion fonctionne) :
    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
     
     
    int main (int argc, char * argv[]) {
     
    	struct sockaddr_in adresse;
    	int    sock;
     
    	int    nb_lus;
     
    	Request operationDemande;
    	Response resultat;
     
    	//... ok jusque là, partie connexion serveur ok
    	while (1) {
    		printf("Opération à effectuer : ");
     
    		if (write(sock, & (operationDemande.operande1), sizeof(Request)) < 0) {
    			perror("write");
    			break;
    		}
    		if (nb_lus = read(sock, & (operationDemande.operande1), sizeof(Request))== 0) 
    			break;
     
    		if (nb_lus < 0) {
    			perror("read");
    			break;
    		}
    		printf("Résultat : ");
     
    	}
    	return EXIT_SUCCESS;
    	}
    Et côté serveur - partie appli
    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
     
    void traitement_connexion (int sock) {
     
    	int longueur;
    	Request operationDemande;
    	Response resultat;
     
    	while (1) {
    		longueur = read(sock, &(operationDemande.operande1),sizeof(Request));
     
    		if (longueur < 0) {
    			perror("read");
    			exit(EXIT_SUCCESS);		
    			}
     
    		if (longueur == 0)
    		  break;
     
    		 printf("recu : %d\n", operationDemande.operande1);
    		 fflush(stdout);
     
    		 write(sock,&(operationDemande.operande1),sizeof(Request));
     
     
    		}
    		close(sock);
    	}
    Je ne vois pas trop comment y parvenir. L'idée serait de faire sur le shell du client, une fois la connexion établie quelque chose du style :
    $ p 5
    et en retour :
    $ 5 est un nombre premier

    Toute aide serait utile,
    Merci d'avance

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 054
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 054
    Billets dans le blog
    141
    Par défaut
    Bonjour,

    Coté client, vous faites un scanf, ou équivalent, pour récupérer l'entrée. Ensuite vous faites une analyse, pour construire la Request à partir de la ligne récupérée. Ensuite, vous envoyez la Request et le serveur répondra.
    La réponse du serveur pourra être soit, la chaine finale à afficher et le client ne fera que l'afficher. Soit juste le nombre résultat et c'est au client d'afficher ce qu'il faut.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Février 2012
    Messages : 21
    Par défaut
    bonjour,

    merci pour le petit coup de main. J'ai pu avancer. Cependant, ça fait des années que je n'ai pas fait de C. Je suis rouillé. Je suis parti dans l'optique que le serveur fera le traitement en fonction des ordres envoyés par le client, et retournera une chaine au client du style :
    client :
    $ p 5
    et réponse :
    $ le nombre 5 est un nombre premier.

    J'envoie bien les paramètres et le serveur les reçoit bien. Pas de problème à ce niveau. Je pense partir sur la voie suivante, en gros :
    sur le serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    switch (operationDemande.operateur) {
    		case 'p': 
                    resultat.result = est_premier(operationDemande.operande1);
                    break;
    (...)
     write(sock,&resultat,sizeof(Response));
    J'ai bien entendu modifié ma structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct Response {
    	char result;
    	};
    typedef struct Response Response;
    Là où je coince un peu, c'est dans la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     char  * est_premier(int nbre)
    où le nbre correspond au paramètre nombre récupéré depuis le client. Je voudrais une chaîne en retour de la forme "Le nombre xxx est premier". Je ne sais plus comment procéder en C pour avoir ça (et avec le jeu des pointeurs, c'est encore pire).

    Merci d'avance

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

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

    Citation Envoyé par roswellenshort Voir le message
    Là où je coince un peu, c'est dans la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     char  * est_premier(int nbre)
    où le nbre correspond au paramètre nombre récupéré depuis le client. Je voudrais une chaîne en retour de la forme "Le nombre xxx est premier". Je ne sais plus comment procéder en C pour avoir ça (et avec le jeu des pointeurs, c'est encore pire).

    Merci d'avance
    C'est possible mais comme il n'y a pas à proprement parler de type « chaîne de caractères » en C, il faudra d'abord allouer de l'espace mémoire avec malloc(), puis construire cette chaîne dans cet espace avec sprintf(), renvoyer le pointeur vers cet espace et, enfin, laisser la fonction appelante libérer cet espace avec free() lorsqu'elle n'en aura plus besoin.

    C'est assez contraignant et pas vraiment orthodoxe dans cette situation. En général, les fonctions de vérification écrites avec le verbe « être » (« est » ou « is ») sont faites pour renvoyer un booléen (true ou false) qui indique si, oui ou non, la condition est vérifiée. C'est ensuite la fonction appelante qui se chargera elle-même d'écrire une chaîne à l'écran.

  5. #5
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Février 2012
    Messages : 21
    Par défaut
    En y repensant, c'est effectivement ce que je me suis dit. Autant en Java, ou tout autre langage plus "évolué", c'est aisé ; autant là, je vois pas trop.

    Finalement, je pense partir sur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int est_premier(int nbre) {
    	int i = 0;
    	int test=0;
    	if (nbre != 1)
    	   return -1;
     
    	for (i = 2; i < nbre; i++)
        if (nbre % i == 0)
          test = 1;
          if (!test) {
    		  return 1;
    		  }
    		  else return 0;
    		}
    Ensuite, dans le code serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    char resultat[256];
    switch (operationDemande.operateur) {
    		case 'p':
    		   test_valeur = est_premier(operationDemande.operande1);
                       if (test_valeur == 1) 
                           sprintf(resultat, "le nombre %d est premier", operationDemande.operande1);
                             else //blabla
    puis envoyer cette variable resultat dans le socket pour la récupérer et l'afficher sur le serveur. Est-ce une solution envisageable ?

  6. #6
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Février 2012
    Messages : 21
    Par défaut
    Auto-réponse :

    visiblement, ça fonctionne. Merci Obsidian pour la piste. Je transmets bien 2 paramètres (un char, un double) et le serveur fait sa moulinette. En revanche, j'ai remarqué que côté client, il attend d'abord un char, suivi d'un double. Si par malheur, je rentre un char, suivi d'un autre char, le programme bug complètement.
    Y'a t'il un moyen de forcer le client à entrer en repetant d'entrer un double tant que c'est pas bon. Quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    do {
       scanf ("%lf",&operationDemande.operande1);
     
    }
    while //operande n'est pas de type attendu
    Merci

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 442
    Par défaut
    Bravo pour avoir résolu ton problème seul.

    Pour la saisie, il est vrai que scanf(), pourtant très répandue dans les tutoriaux, est loin d'être une fonction facile. Cela dit, la man page correspondante indique qu'elle renvoie le nombre d'arguments correctement interprétés et initialisés. Tu peux examiner cette valeur de retour et faire un tour de boucle si elle est inférieure au nombre attendu.

  8. #8
    Membre averti
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Février 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Février 2012
    Messages : 21
    Par défaut
    Merci pour le coup de main. J'ai mon petit serveur d'application qui fonctionne et retourne des résultats cohérents (excepté le fait qu'il bug en cas de char tapé deux fois, mais là n'est pas le but du petit exercice).

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

Discussions similaires

  1. Quel version de linux pr un serveur d'application maison
    Par vinou94400 dans le forum Développement Web en Java
    Réponses: 2
    Dernier message: 28/01/2012, 11h48
  2. Socket client/serveur Linux
    Par Ccabrel dans le forum C
    Réponses: 2
    Dernier message: 14/10/2009, 01h15
  3. comment installer logiciel libre sur un serveur d'application sous Linux (Débian)
    Par meriem_inf dans le forum Applications et environnements graphiques
    Réponses: 1
    Dernier message: 01/09/2009, 12h56
  4. Réponses: 2
    Dernier message: 23/03/2009, 12h11
  5. Réponses: 2
    Dernier message: 12/10/2004, 13h04

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