Socket Linux

Socket Linux - C - Programmation

Marsh Posté le 11-10-2009 à 02:56:13    

Bonjour à tous,
 Je suis nouveau sur ce forum et j'ai fini mes études info il y a trois ans. Mais je continu en cours du soir au CNAM.
J'ai fait des études info en réseau et pour mes cours j'ai un projet que je doit faire sous Linux en C, et la programmation, c'est pas mon fort !!!
Je vous soumets donc mon sujet :  
 
« Écrire un programme permettant la mise en place de services bancaires. Les services sont les suivants :
- affichage du solde de compte (valeur et débit/crédit)
- affichage de l'intitulé du compte (nom, prénom, adresse, numéro de compte)
Le fonctionnement de ces services est un mode client/serveur qui permet un fonctionnement en réseau de l'application. Le port d'écoute du serveur est 1444.  
Le serveur permet de traiter plusieurs opérations en parallèle. Lors d'une même transaction le client peut demander la réalisation des 2 services ou d'un seul. La communication entre le serveur et le client doit donc prendre en compte une demande identifiée de service.
Sur le serveur, un processus de gestion des appels doit être actif, il permet de tracer l'ensemble des appels et les demandes de service réalisé. Ce processus doit pouvoir afficher, le contenu de son journal sur demande.
Pour simplifier, le travail de programmation les structures correspondant aux informations des comtes bancaires sont stockées en mémoire centrale. Les demandes de services sont réalisés à partir du numéro de compte bancaire.
1) Décrivez le mode de fonctionnement de cette application en précisant le outils de communication utilisés. Précisez, pour chaque outil les raisons de votre choix.
2) Écrivez l'ensemble des programmes permettant de réaliser l'ensemble de ces services. Les programmes doivent être commentés afin d'en faciliter la lecture. »
 
Si quelqu'un se sent peut m'aider...je n'ai pas besoin d'un programme super compliqué, mais au contraire plus il sera simple, mieux j'aurai des chance de le comprendre...et comme demandé dans le sujet, les commentaires sont indispensable pour moi...
 
Un dernier petit détail, j'habite en Nouvelle Calédonie, donc si je ne répond pas rapidement àvos questions éventuelles, c'est sûrement du au décalage horaire...quand vous vous couchez, je part au boulot...
 
Merci d'avance à tous ceux qui pourront m'aider...

Reply

Marsh Posté le 11-10-2009 à 02:56:13   

Reply

Marsh Posté le 12-10-2009 à 10:53:20    

J'ai un ami qui peut vous aider. Il s'appelle Google.
 
(Désolé, mais ne peut pas écrire de très longs messages sur un forum comme celui-ci, et donc on ne peut pas expliquer toute la théorie de TCP/IP ou d'UDP/IP. Voyer plutôt les tutoriaux, sur TCP/IP ou UDP/IP (en premier lieu, il faut choisir l'un de ces deux modes) et voir aussi les exemples de codes source qui existent aussi certainement sur internet.)

Reply

Marsh Posté le 12-10-2009 à 21:53:38    

Ici tu trouveras le cours que je donnais en 2000 sur les socket Unix: http://fr.lang.free.fr/cours/SocketCsyst_v1.0.pdf
 
Et voici plusieurs exemples simplistes de communications via socket. Tous ces programmes font la même chose: le client fait saisir une chaine et l'envoie au serveur qui l'affiche.
Ils sont un peu vieux (2000) mais devraient quand-même se compiler sans problème. Ptet qq warnings mais rien de plus.
 
Exemple1: communication à travers un fichier socket - Ca ne fonctionne que si le client et le serveur sont sur la même machine
Le serveur

Code :
  1. #include <sys/types.h>                        // Types prédéfinis "c"          
  2. #include <sys/socket.h>                        // Généralités sockets            
  3. #include <sys/un.h>                            // Spécifications socket unix    
  4. #include <stdio.h>                            // I/O fichiers classiques        
  5. #include <signal.h>                            // Signaux de communication      
  6. #include <errno.h>                            // Erreurs système                
  7.  
  8. extern const char* const sys_errlist[];        // Liste messages erreurs        
  9.  
  10. #define NAME_SOCKET            ("socket_file" )    // Nom fichier socket            
  11. #define SZ_BUF                (256)            // Taille buffer                  
  12.  
  13. main(
  14.     int argc,                                 // Nbre arguments                
  15.     char *argv[])                            // Ptr arguments                  
  16. {
  17.     // Déclaration des variables
  18.     int sk_creat;                            // Socket de création            
  19.     int sk_dialog;                            // Socket de dialogue            
  20.     int pid;                                // Process créé                  
  21.     int sz_read;                            // Nombre octets lus              
  22.  
  23.     char buf[SZ_BUF];                        // Buffer texte                  
  24.  
  25.     struct sockaddr_un adr_serveur;            // Adresse socket serveur        
  26.  
  27.     // Détournement du signal émis à la mort du fils (il ne reste pas zombie)
  28.     signal(SIGCHLD, SIG_IGN);
  29.  
  30.     // Effacement fichier socket résiduel
  31.     unlink(NAME_SOCKET);
  32.  
  33.     // Création socket
  34.     if ((sk_creat=socket(AF_UNIX, SOCK_STREAM, 0)) == (-1))
  35.     {
  36.         fprintf(stderr, "ligne %u - socket() - %s\n", __LINE__, sys_errlist[errno]);
  37.         exit(errno);
  38.     }
  39.  
  40.     // Remplissage adresse socket
  41.     memset(&adr_serveur, 0, sizeof(struct sockaddr_un));
  42.     adr_serveur.sun_len=strlen(NAME_SOCKET) + 1;
  43.     adr_serveur.sun_family=AF_UNIX;
  44.     memcpy(&(adr_serveur.sun_path), NAME_SOCKET, strlen(NAME_SOCKET));
  45.  
  46.     // Identification socket/réseau
  47.     if (bind(sk_creat, &adr_serveur, sizeof(struct sockaddr_un)) == (-1))
  48.     {
  49.         fprintf(stderr, "ligne %u - bind() - %s\n", __LINE__, sys_errlist[errno]);
  50.         exit(errno);
  51.     }
  52.  
  53.     // Prise de la ligne
  54.     listen(sk_creat, 1);
  55.  
  56.     // Ecoute permanente
  57.     fputc('\n', stdout);
  58.     while (1)
  59.     {
  60.         printf("ppid=%u, pid=%u\tAttente entrée...", getppid(), getpid());
  61.         fflush(stdout);
  62.  
  63.         // Attente connexion client
  64.         if ((sk_dialog=accept(sk_creat, NULL, NULL)) == (-1))
  65.         {
  66.             fprintf(stderr, "ligne %u - accept() - %s\n", __LINE__, sys_errlist[errno]);
  67.             exit(errno);
  68.         }
  69.         fputs("Entrée émise\n", stdout);
  70.         
  71.         // Duplication du process
  72.         switch (pid=fork())
  73.         {
  74.             case (-1): // Erreur de fork
  75.                 close(sk_creat);
  76.                 close(sk_dialog);
  77.                 fprintf(stderr, "ligne %u - fork() - %s\n", __LINE__, sys_errlist[errno]);
  78.                 exit(errno);
  79.  
  80.             case 0: // Fils
  81.                 // Fermeture socket inutilisée
  82.                 close(sk_creat);
  83.  
  84.                 // Lecture en boucle sur la socket
  85.                 while ((sz_read=read(sk_dialog, buf, SZ_BUF)) > 0)
  86.                 {
  87.                     printf("\n\tppid=%u, pid=%u\tLe serveur a lu '%s'%s\n", getppid(), getpid(), buf, strcmp(buf, "EOT" ) != 0 ?"" :"=> Fin de communication" );
  88.  
  89.                     // Si la chaine contient "EOT"
  90.                     if (strcmp(buf, "EOT" ) == 0)
  91.                         break;
  92.                 }
  93.  
  94.                 // Si l'arrêt de la lecture est dû à ne erreur
  95.                 if (sz_read == (-1))
  96.                 {
  97.                     close(sk_dialog);
  98.                     fprintf(stderr, "ligne %u - read() - %s\n", __LINE__, sys_errlist[errno]);
  99.                     exit(errno);
  100.                 }
  101.  
  102.                 // Fin du fils
  103.                 close(sk_dialog);
  104.                 exit(0);
  105.  
  106.             default: // Père
  107.                 close(sk_dialog);
  108.         }
  109.     }
  110.     // Pas de sortie du programme - Boucle infinie
  111.  
  112.     // Fermeture socket et fin théorique du programme (pour être propre)
  113.     close(sk_creat);
  114. }


 
Le client

Code :
  1. #include <sys/types.h>                        // Types prédéfinis "c"          
  2. #include <sys/socket.h>                        // Généralités sockets            
  3. #include <sys/un.h>                            // Spécifications socket unix    
  4. #include <stdio.h>                            // I/O fichiers classiques        
  5. #include <string.h>                            // Gestion chaines de caractères  
  6. #include <errno.h>                            // Erreurs système                
  7.  
  8. extern const char* const sys_errlist[];        // Liste messages erreurs        
  9.  
  10. #define NAME_SOCKET            ("socket_file" )    // Nom fichier socket            
  11. #define SZ_BUF                (256)            // Taille buffer                  
  12.  
  13. main(
  14.     int argc,                                 // Nbre arguments                
  15.     char *argv[])                            // Ptr arguments                  
  16. {
  17.     // Déclaration des variables
  18.     int sk_connect;                            // Socket de connection          
  19.     int sk_dialog;                            // Socket de dialogue            
  20.  
  21.     char buf[SZ_BUF];                        // Buffer texte                  
  22.     char *pt;                                // Ptr vers un caractère qcq.    
  23.  
  24.     struct sockaddr_un adr_serveur;            // Adresse socket serveur        
  25.  
  26.     // Remplissage adresse socket
  27.     memset(&adr_serveur, 0, sizeof(struct sockaddr_un));
  28.     adr_serveur.sun_len=strlen(NAME_SOCKET) + 1;
  29.     adr_serveur.sun_family=AF_UNIX;
  30.     memcpy(&adr_serveur.sun_path, NAME_SOCKET, strlen(NAME_SOCKET));
  31.  
  32.     // Tentative de connection en boucle permanente
  33.     fputc('\n', stdout);
  34.     do
  35.     {
  36.         // Création socket
  37.         if ((sk_dialog=socket(AF_UNIX, SOCK_STREAM, 0)) == (-1))
  38.         {
  39.             fprintf(stderr, "ligne %u - socket() - %s\n", __LINE__, sys_errlist[errno]);
  40.             exit(errno);
  41.         }
  42.  
  43.         // Connection au serveur
  44.         if ((sk_connect=connect(sk_dialog, &adr_serveur, sizeof(struct sockaddr_un))) == (-1))
  45.         {
  46.             fprintf(stderr, "ligne %u - connect() - %s\n", __LINE__, sys_errlist[errno]);
  47.             sleep(5);
  48.         }
  49.     }
  50.     while (sk_connect == (-1));
  51.     printf("Connection réussie\n" );
  52.  
  53.     // Saisie et envoi de la chaîne en boucle
  54.     do
  55.     {
  56.         // Saisie de la chaîne
  57.         fputs("Entrer chaine (EOT pour finir) :", stdout); fflush(stdout);
  58.         fflush(stdin); fgets(buf, SZ_BUF, stdin);
  59.  
  60.         // Suppression de la chaîne saisie le caractère '\n' s'il y est
  61.         if ((pt=strchr(buf, '\n')) != NULL)
  62.             *pt='\0';
  63.  
  64.         // Envoi de la chaîne modifiée sur la socket
  65.         if (write(sk_dialog, buf, strlen(buf) + 1) == (-1))
  66.             fprintf(stderr, "ligne %u - write(%s) - %s\n", __LINE__, buf, sys_errlist[errno]);
  67.     }
  68.     while (strcmp(buf, "EOT" ) != 0);
  69.  
  70.     // Fermeture socket et fin du programme
  71.     close(sk_dialog);
  72. }


 
Exemple2: communication en tcp.  
Le serveur

Code :
  1. #include <sys/types.h>                        // Types prédéfinis "c"          
  2. #include <sys/socket.h>                        // Généralités sockets            
  3. #include <sys/param.h>                        // Paramètres et limites système  
  4. #include <netinet/in.h>                        // Spécifications socket internet
  5. #include <arpa/inet.h>                        // Adresses format "arpanet"      
  6. #include <signal.h>                            // Signaux de communication      
  7. #include <stdio.h>                            // I/O fichiers classiques        
  8. #include <netdb.h>                            // Gestion network database      
  9. #include <errno.h>                            // Erreurs système                
  10.  
  11. extern const char* const sys_errlist[];        // Liste messages erreurs        
  12.  
  13. #define SERVICE_LABEL        ("toto" )        // Nom service requis            
  14. #define SERVICE_PROTOCOL    ("tcp" )            // Protocole service requis      
  15. #define SZ_BUF                (256)            // Taille buffer                  
  16.  
  17. main(
  18.     int argc,                                 // Nbre arguments                
  19.     char *argv[])                            // Ptr arguments                  
  20. {
  21.     // Déclaration des variables
  22.     ushort i;                                // Indice de boucle              
  23.     ushort j;                                // Indice de boucle              
  24.  
  25.     int sk_creat;                            // Socket de création            
  26.     int sk_dialog;                            // Socket de dialogue            
  27.     int pid;                                // Process créé                  
  28.     int len_adr;                            // Taille adresse                
  29.     int sz_read;                            // Nbre octets lus                
  30.  
  31.     char buf[SZ_BUF];                        // Buffer texte                  
  32.     char hostname[MAXHOSTNAMELEN + 1];        // Nom machine locale            
  33.  
  34.     struct sockaddr_in adr_serveur;            // Adresse socket serveur        
  35.     struct sockaddr_in adr_client;            // Adresse socket client          
  36.     struct hostent *host_info;                // Info. host client connecté    
  37.     struct servent *service_info;            // Info. service demandé          
  38.  
  39.     char *adr_ascii;                        // Adresse client mode ascii      
  40.  
  41.     // Détournement du signal émis à la mort du fils (il ne reste pas zombie)
  42.     signal(SIGCHLD, SIG_IGN);
  43.  
  44.     // Récuperation nom machine locale (juste pour l'exemple)
  45.     if (gethostname(hostname, MAXHOSTNAMELEN) != 0)
  46.     {
  47.         fprintf(stderr, "ligne %u - gethostname(%s) - %s\n", __LINE__, hostname, sys_errlist[errno]);
  48.         exit(errno);
  49.     }
  50.     printf("gethostname='%s'\n", hostname);
  51.  
  52.     // Récuperation port dans "/etc/services"
  53.     if ((service_info=getservbyname(SERVICE_LABEL, SERVICE_PROTOCOL)) == NULL)
  54.     {
  55.         fprintf(stderr, "ligne %u - getservbyname(%s, %s) - %s\n", __LINE__, SERVICE_LABEL, SERVICE_PROTOCOL, sys_errlist[errno]);
  56.         exit(errno);
  57.     }
  58.     fputc('\n', stdout);
  59.     printf("service_name='%s'\n", service_info->s_name);
  60.     for (i=0; service_info->s_aliases[i] != NULL; i++)
  61.         printf("service_s_aliase[%hu]='%s'\n", i, service_info->s_aliases[i]);
  62.     printf("service_port=%u\n", ntohs(service_info->s_port));
  63.     printf("service_protocole='%s'\n", service_info->s_proto);
  64.  
  65.     // Création socket
  66.     if ((sk_creat=socket(AF_INET, SOCK_STREAM, 0)) == (-1))
  67.     {
  68.         fprintf(stderr, "ligne %u - socket() - %s\n", __LINE__, sys_errlist[errno]);
  69.         exit(errno);
  70.     }
  71.     printf("Socket créée\n" );
  72.  
  73.     // Remplissage adresse socket
  74.     memset(&adr_serveur, 0, sizeof(struct sockaddr_in));
  75.     adr_serveur.sin_family=AF_INET;
  76.     adr_serveur.sin_port=service_info->s_port;
  77.     adr_serveur.sin_addr.s_addr=INADDR_ANY;
  78.  
  79.     // Identification socket/réseau
  80.     if (bind(sk_creat, &adr_serveur, sizeof(struct sockaddr_in)) == (-1))
  81.     {
  82.         fprintf(stderr, "ligne %u - bind() - %s\n", __LINE__, sys_errlist[errno]);
  83.         exit(errno);
  84.     }
  85.     printf("Socket connectée au réseau\n" );
  86.  
  87.     // Ecoute de la ligne
  88.     listen(sk_creat, 1);
  89.  
  90.     // Attente permanente
  91.     fputc('\n', stdout);
  92.     while (1)
  93.     {
  94.         printf("ppid=%u, pid=%u\tAttente entrée...", getppid(), getpid());
  95.         fflush(stdout);
  96.  
  97.         // Attente connexion client
  98.         len_adr=sizeof(struct sockaddr_in);
  99.         if ((sk_dialog=accept(sk_creat, &adr_client, &len_adr)) == (-1))
  100.         {
  101.             fprintf(stderr, "ligne %u - accept() - %s\n", __LINE__, sys_errlist[errno]);
  102.             exit(errno);
  103.         }
  104.  
  105.         // Client connecté
  106.         fputs("Entrée émise ", stdout);
  107.  
  108.         // Transformation adresse net en ascii
  109.         if ((adr_ascii=inet_ntoa(adr_client.sin_addr)) > (char*)0)
  110.         {
  111.             printf("(adr=%s", adr_ascii);
  112.  
  113.             // Récupération informations sur client par son adresse
  114.             if ((host_info=gethostbyaddr((char*)&adr_client.sin_addr.s_addr, sizeof(struct in_addr), AF_INET)) != NULL)
  115.                 printf(" - %s)\n", host_info->h_name);
  116.             else
  117.             {
  118.                 fputs("- ???)\n", stdout);
  119.                 fprintf(stderr, "ligne %u - gethostbyaddr() - %s\n", __LINE__, sys_errlist[errno]);
  120.             }
  121.         }
  122.         else
  123.         {
  124.             fputs("(adr=???)\n", stdout);
  125.             fprintf(stderr, "ligne %u - inet_ntoa() - %s\n", __LINE__, sys_errlist[errno]);
  126.         }
  127.         
  128.         // Duplication du process
  129.         switch (pid=fork())
  130.         {
  131.             case (-1): // Erreur de fork
  132.                 close(sk_creat);
  133.                 close(sk_dialog);
  134.                 fprintf(stderr, "ligne %u - fork() - %s\n", __LINE__, sys_errlist[errno]);
  135.                 exit(errno);
  136.  
  137.             case 0: // Fils
  138.                 // Fermeture socket inutilisée
  139.                 close(sk_creat);
  140.  
  141.                 // Lecture en boucle sur la socket
  142.                 while ((sz_read=read(sk_dialog, buf, SZ_BUF)) > 0)
  143.                 {
  144.                     printf("\n\tppid=%u, pid=%u\tLe serveur a lu '%s'%s\n", getppid(), getpid(), buf, strcmp(buf, "EOT" ) != 0 ?"" :"=> Fin de communication" );
  145.  
  146.                     // Si la chaine contient "EOT"
  147.                     if (strcmp(buf, "EOT" ) == 0)
  148.                         break;
  149.                 }
  150.  
  151.                 // Si l'arrêt de la lecture est dû à une erreur
  152.                 if (sz_read == (-1))
  153.                 {
  154.                     close(sk_dialog);
  155.                     fprintf(stderr, "ligne %u - read() - %s\n", __LINE__, sys_errlist[errno]);
  156.                     exit(errno);
  157.                 }
  158.  
  159.                 // Fin du fils
  160.                 close(sk_dialog);
  161.                 exit(0);
  162.  
  163.             default: // Père
  164.                 close(sk_dialog);
  165.         }
  166.     }
  167.     // Pas de sortie de programme - Boucle infinie
  168.  
  169.     // Fermeture socket et fin théorique du programme (pour être propre)
  170.     close(sk_creat);
  171. }


 
Le client

Code :
  1. #include <sys/types.h>                        // Types prédéfinis "c"          
  2. #include <sys/socket.h>                        // Généralités sockets            
  3. #include <sys/param.h>                        // Paramètres et limites système  
  4. #include <netinet/in.h>                        // Spécifications socket internet
  5. #include <stdio.h>                            // I/O fichiers classiques        
  6. #include <string.h>                            // Gestion chaines de caractères  
  7. #include <netdb.h>                            // Gestion network database      
  8. #include <errno.h>                            // Erreurs système                
  9.  
  10. extern const char* const sys_errlist[];        // Liste messages erreurs        
  11.  
  12. #define SERVEUR_DEFAULT        ("localhost" )    // Nom serveur utilisé par défaut
  13. #define SERVICE_LABEL        ("toto" )        // Nom service requis            
  14. #define SERVICE_PROTOCOL    ("tcp" )            // Protocole service requis      
  15. #define SZ_BUF                (256)            // Taille buffer                  
  16.  
  17. main(
  18.     int argc,                                 // Nbre arguments                
  19.     char *argv[])                            // Ptr arguments                  
  20. {
  21.     // Déclaration des variables
  22.     ushort i;                                // Indice de boucle              
  23.     ushort j;                                // Indice de boucle              
  24.  
  25.     int sk_connect;                            // Socket de connection          
  26.     int sk_dialog;                            // Socket de dialogue            
  27.  
  28.     char buf[SZ_BUF];                        // Buffer texte                  
  29.     char hostname[MAXHOSTNAMELEN + 1];        // Nom machine locale            
  30.     char *serveur;                            // Ptr vers le nom du serveur    
  31.     char *pt;                                // Ptr vers un caractère qcq.    
  32.  
  33.     struct sockaddr_in adr_serveur;            // Adresse socket serveur        
  34.     struct hostent *host_info;                // Info. host                    
  35.     struct servent *service_info;            // Info. service demandé          
  36.  
  37.     // Remplissage du nom du serveur
  38.     if (argc > 1)
  39.         // Le nom du serveur est l'argument n° 1
  40.         serveur=argv[1];
  41.     else
  42.     {
  43.         // Le nom du serveur est pris par défaut
  44.         serveur=SERVEUR_DEFAULT;
  45.         printf("Pas d'argument pour %s - Utilisation de %s\n", *argv, SERVEUR_DEFAULT);
  46.     }
  47.  
  48.     // Récuperation nom machine locale (juste pour l'exemple)
  49.     if (gethostname(hostname, MAXHOSTNAMELEN) != 0)
  50.     {
  51.         fprintf(stderr, "ligne %u - gethostname(%s) - %s\n", __LINE__, hostname, sys_errlist[errno]);
  52.         exit(errno);
  53.     }
  54.     printf("gethostname='%s'\n", hostname);
  55.  
  56.     // Récuperation informations serveur
  57.     if ((host_info=gethostbyname(serveur)) == NULL)
  58.     {
  59.         fprintf(stderr, "ligne %u - gethostbyname(%s) - %s\n", __LINE__, serveur, sys_errlist[errno]);
  60.         exit(errno);
  61.     }
  62.     fputc('\n', stdout);
  63.     printf("host_info.h_name='%s'\n", host_info->h_name);
  64.     for (i=0; host_info->h_aliases[i] != NULL; i++)
  65.         printf("host_info.h_aliase[%hu]='%s'\n", i, host_info->h_aliases[i]);
  66.     printf("host_info.h_addrtype=%u\n", host_info->h_addrtype);
  67.     printf("host_info.h_length=%u\n", host_info->h_length);
  68.     for (i=0; host_info->h_addr_list[i] != NULL; i++)
  69.     {
  70.         printf("host_info.h_addr_list[%hu]=", i);
  71.         for (j=0; j < host_info->h_length; j++)
  72.             printf("%hu ", (unsigned char)host_info->h_addr_list[i][j]);
  73.         fputc('\n', stdout);
  74.     }
  75.  
  76.     // Récuperation port dans "/etc/services"
  77.     if ((service_info=getservbyname(SERVICE_LABEL, SERVICE_PROTOCOL)) ==NULL)
  78.     {
  79.         fprintf(stderr, "ligne %u - getservbyname(%s, %s) - %s\n", __LINE__, SERVICE_LABEL, SERVICE_PROTOCOL, sys_errlist[errno]);
  80.         exit(errno);
  81.     }
  82.     fputc('\n', stdout);
  83.     printf("service_name='%s'\n", service_info->s_name);
  84.     for (i=0; service_info->s_aliases[i] != NULL; i++)
  85.         printf("service_s_aliase[%hu]='%s'\n", i, service_info->s_aliases[i]);
  86.     printf("service_port=%u\n", ntohs(service_info->s_port));
  87.     printf("service_protocole='%s'\n", service_info->s_proto);
  88.  
  89.     // Remplissage adresse socket
  90.     memset(&adr_serveur, 0, sizeof(struct sockaddr_in));
  91.     adr_serveur.sin_len=host_info->h_length;
  92.     adr_serveur.sin_family=AF_INET;
  93.     adr_serveur.sin_port=service_info->s_port;
  94.     memcpy(&adr_serveur.sin_addr.s_addr, host_info->h_addr, host_info->h_length);
  95.  
  96.     // Tentative de connection en boucle permanente
  97.     fputc('\n', stdout);
  98.     do {
  99.         // Création socket
  100.         if ((sk_dialog=socket(AF_INET, SOCK_STREAM, 0)) == (-1))
  101.         {
  102.             fprintf(stderr, "ligne %u - socket() - %s\n", __LINE__, sys_errlist[errno]);
  103.             exit(errno);
  104.         }
  105.  
  106.         // Connection au serveur
  107.         if ((sk_connect=connect(sk_dialog, &adr_serveur, sizeof(struct sockaddr_in))) == (-1))
  108.         {
  109.             fprintf(stderr, "ligne %u - connect() - %s\n", __LINE__, sys_errlist[errno]);
  110.             sleep(5);
  111.         }
  112.     } while (sk_connect == (-1));
  113.     printf("Connection réussie\n" );
  114.  
  115.     // Saisie et envoi de la chaîne en boucle
  116.     do {
  117.         // Saisie de la chaîne
  118.         fputs("Entrer chaine (EOT pour finir) :", stdout); fflush(stdout);
  119.         fflush(stdin); fgets(buf, SZ_BUF, stdin);
  120.  
  121.         // Suppression de la chaîne saisie le caractère '\n' s'il y est
  122.         if ((pt=strchr(buf, '\n')) != NULL)
  123.             *pt='\0';
  124.  
  125.         // Envoi de la chaîne modifiée sur la socket
  126.         if (write(sk_dialog, buf, strlen(buf) + 1) == (-1))
  127.             fprintf(stderr, "ligne %u - write(%s) - %s\n", __LINE__, buf, sys_errlist[errno]);
  128.     } while (strcmp(buf, "EOT" ) != 0);
  129.  
  130.     // Fermeture socket et fin du programme
  131.     close(sk_dialog);
  132.     exit(0);
  133. }


Il faudra créer une entrée "toto" en mode "tcp" dans "/etc/services" pour que le client et le serveur puissent récupérer un n° de port
 
Exemple3: communication en udp
Le serveur

Code :
  1. #include <sys/types.h>                        // Types prédéfinis "c"          
  2. #include <sys/socket.h>                        // Généralités sockets            
  3. #include <sys/param.h>                        // Paramètres et limites système  
  4. #include <netinet/in.h>                        // Spécifications socket internet
  5. #include <arpa/inet.h>                        // Adresses format "arpanet"      
  6. #include <stdio.h>                            // I/O fichiers classiques        
  7. #include <netdb.h>                            // Gestion network database      
  8. #include <errno.h>                            // Erreurs système                
  9.  
  10. extern const char* const sys_errlist[];        // Liste messages erreurs        
  11.  
  12. #define SERVICE_LABEL        ("toto" )        // Nom service requis            
  13. #define SERVICE_PROTOCOL    ("udp" )            // Protocole service requis      
  14. #define SZ_BUF                (256)            // Taille buffer                  
  15.  
  16. main(
  17.     int argc,                                 // Nbre arguments                
  18.     char *argv[])                            // Ptr arguments                  
  19. {
  20.     // Déclaration des variables
  21.     ushort i;                                // Indice de boucle              
  22.     ushort j;                                // Indice de boucle              
  23.  
  24.     int sk_dialog;                            // Socket de dialogue            
  25.     int len_adr;                            // Taille adresse                
  26.  
  27.     char buf[SZ_BUF];                        // Buffer texte                  
  28.     char hostname[MAXHOSTNAMELEN + 1];        // Nom machine locale            
  29.  
  30.     struct sockaddr_in adr_serveur;            // Adresse socket serveur        
  31.     struct sockaddr_in adr_client;            // Adresse socket client          
  32.     struct hostent *host_info;                // Info. host client connecté    
  33.     struct servent *service_info;            // Info. service demandé          
  34.  
  35.     char *adr_ascii;                        // Adresse client mode ascii      
  36.  
  37.     // Récuperation nom machine locale (juste pour l'exemple)
  38.     if (gethostname(hostname, MAXHOSTNAMELEN) != 0)
  39.     {
  40.         fprintf(stderr, "ligne %u - gethostname(%s) - %s\n", __LINE__, hostname, sys_errlist[errno]);
  41.         exit(errno);
  42.     }
  43.     printf("gethostname='%s'\n", hostname);
  44.  
  45.     // Récuperation port dans "/etc/services"
  46.     if ((service_info=getservbyname(SERVICE_LABEL, SERVICE_PROTOCOL)) == NULL)
  47.     {
  48.         fprintf(stderr, "ligne %u - getservbyname(%s, %s) - %s\n", __LINE__, SERVICE_LABEL, SERVICE_PROTOCOL, sys_errlist[errno]);
  49.         exit(errno);
  50.     }
  51.     fputc('\n', stdout);
  52.     printf("service_name='%s'\n", service_info->s_name);
  53.     for (i=0; service_info->s_aliases[i] != NULL; i++)
  54.         printf("service_s_aliase[%hu]='%s'\n", i, service_info->s_aliases[i]);
  55.     printf("service_port=%u\n", ntohs(service_info->s_port));
  56.     printf("service_protocole='%s'\n", service_info->s_proto);
  57.  
  58.     // Création socket
  59.     if ((sk_dialog=socket(AF_INET, SOCK_DGRAM, 0)) == (-1))
  60.     {
  61.         fprintf(stderr, "ligne %u - socket() - %s\n", __LINE__, sys_errlist[errno]);
  62.         exit(errno);
  63.     }
  64.     fputs("Socket créée\n", stdout);
  65.  
  66.     // Remplissage adresse socket
  67.     memset(&adr_serveur, 0, sizeof(struct sockaddr_in));
  68.     adr_serveur.sin_family=AF_INET;
  69.     adr_serveur.sin_port=service_info->s_port;
  70.     adr_serveur.sin_addr.s_addr=INADDR_ANY;
  71.  
  72.     // Identification socket/réseau
  73.     if (bind(sk_dialog, &adr_serveur, sizeof(struct sockaddr_in)) == (-1))
  74.     {
  75.         fprintf(stderr, "ligne %u - bind() - %s\n", __LINE__, sys_errlist[errno]);
  76.         exit(errno);
  77.     }
  78.     fputs("Socket reliée au réseau\n", stdout);
  79.  
  80.     // Lecture en boucle sur la socket
  81.     len_adr=sizeof(struct sockaddr_in);
  82.     while (1)
  83.     {
  84.         if (recvfrom(sk_dialog, buf, SZ_BUF, 0, &adr_client, &len_adr) == (-1))
  85.             fprintf(stderr, "ligne %u - recvfrom() - %s\n", __LINE__, sys_errlist[errno]);
  86.  
  87.         // Transformation adresse client en ascii
  88.         if ((adr_ascii=inet_ntoa(adr_client.sin_addr)) > (char*)0)
  89.         {
  90.             printf("From client %s ", adr_ascii);
  91.  
  92.             // Récupération informations sur client par son adresse
  93.             if ((host_info=gethostbyaddr((char*)&adr_client.sin_addr.s_addr, sizeof(struct in_addr), AF_INET)) != NULL)
  94.                 printf("(%s)", host_info->h_name);
  95.             else
  96.             {
  97.                 fputs("(???)", stdout);
  98.                 fprintf(stderr, "ligne %u - gethostbyaddr() - %s\n", __LINE__, sys_errlist[errno]);
  99.             }
  100.         }
  101.         else
  102.         {
  103.             fputs("From client ???", stdout);
  104.             fprintf(stderr, "ligne %u - inet_ntoa() - %s\n", __LINE__, sys_errlist[errno]);
  105.         }
  106.         printf(" - Le serveur a lu '%s'%s\n", buf, strcmp(buf, "EOT" ) != 0 ?"" :"=> Fin de communication" );
  107.     }
  108.     // Pas de sortie de programme - Boucle infinie
  109.  
  110.     // Fermeture socket et fin théorique du programme (pour être propre)
  111.     close(sk_dialog);
  112.     exit(0);
  113. }


 
Le client

Code :
  1. #include <sys/types.h>                        // Types prédéfinis "c"          
  2. #include <sys/socket.h>                        // Généralités sockets            
  3. #include <sys/param.h>                        // Paramètres et limites système  
  4. #include <netinet/in.h>                        // Spécifications socket internet
  5. #include <stdio.h>                            // I/O fichiers classiques        
  6. #include <string.h>                            // Gestion chaines de caractères  
  7. #include <netdb.h>                            // Gestion network database      
  8. #include <errno.h>                            // Erreurs système                
  9.  
  10. extern const char* const sys_errlist[];        // Liste messages erreurs        
  11.  
  12. #define SERVEUR_DEFAULT        ("localhost" )    // Nom serveur utilisé par défaut
  13. #define SERVICE_LABEL        ("toto" )        // Nom service requis            
  14. #define SERVICE_PROTOCOL    ("udp" )            // Protocole service requis      
  15. #define SZ_BUF                (256)            // Taille buffer                  
  16.  
  17. main(
  18.     int argc,                                 // Nbre arguments                
  19.     char *argv[])                            // Ptr arguments                  
  20. {
  21.     // Déclaration des variables
  22.     ushort i;                                // Indice de boucle              
  23.     ushort j;                                // Indice de boucle              
  24.  
  25.     int sk_dialog;                            // Socket de dialogue            
  26.  
  27.     char buf[SZ_BUF];                        // Buffer texte                  
  28.     char hostname[MAXHOSTNAMELEN + 1];        // Nom machine locale            
  29.     char *pt;                                // Ptr vers un caractère qcq.    
  30.     char *serveur;                            // Ptr vers le nom du serveur    
  31.  
  32.     struct sockaddr_in adr_serveur;            // Adresse socket serveur        
  33.     struct hostent *host_info;                // Info. host                    
  34.     struct servent *service_info;            // Info. service demandé          
  35.  
  36.     // Remplissage du nom du serveur
  37.     if (argc > 1)
  38.         // Le nom du serveur est l'argument n° 1
  39.         serveur=argv[1];
  40.     else
  41.     {
  42.         // Le nom du serveur est pris par défaut
  43.         serveur=SERVEUR_DEFAULT;
  44.         printf("Pas d'argument pour %s - Utilisation de %s\n", *argv, serveur);
  45.     }
  46.  
  47.     // Récuperation nom machine locale (juste pour l'exemple)
  48.     if (gethostname(hostname, MAXHOSTNAMELEN) != 0)
  49.     {
  50.         fprintf(stderr, "ligne %u - gethostname(%s) - %s\n", __LINE__, hostname, sys_errlist[errno]);
  51.         exit(errno);
  52.     }
  53.     printf("gethostname='%s'\n", hostname);
  54.  
  55.     // Récuperation informations serveur
  56.     if ((host_info=gethostbyname(serveur)) == NULL)
  57.     {
  58.         fprintf(stderr, "ligne %u - gethostbyname(%s) - %s\n", __LINE__, serveur, sys_errlist[errno]);
  59.         exit(errno);
  60.     }
  61.     fputc('\n', stdout);
  62.     printf("host_info.h_name='%s'\n", host_info->h_name);
  63.     for (i=0; host_info->h_aliases[i] != NULL; i++)
  64.         printf("host_info.h_aliase[%hu]='%s'\n", i, host_info->h_aliases[i]);
  65.     printf("host_info.h_addrtype=%u\n", host_info->h_addrtype);
  66.     printf("host_info.h_length=%u\n", host_info->h_length);
  67.     for (i=0; host_info->h_addr_list[i] != NULL; i++)
  68.     {
  69.         printf("host_info.h_addr_list[%hu]=", i);
  70.         for (j=0; j < host_info->h_length; j++)
  71.             printf("%hu ", (unsigned char)host_info->h_addr_list[i][j]);
  72.         fputc('\n', stdout);
  73.     }
  74.  
  75.     // Récuperation port dans "/etc/services"
  76.     if ((service_info=getservbyname(SERVICE_LABEL, SERVICE_PROTOCOL)) == NULL)
  77.     {
  78.         fprintf(stderr, "ligne %u - getservbyname(%s, %s) - %s\n", __LINE__, SERVICE_LABEL, SERVICE_PROTOCOL, sys_errlist[errno]);
  79.         exit(errno);
  80.     }
  81.     fputc('\n', stdout);
  82.     printf("service_name='%s'\n", service_info->s_name);
  83.     for (i=0; service_info->s_aliases[i] != NULL; i++)
  84.         printf("service_s_aliase[%hu]='%s'\n", i, service_info->s_aliases[i]);
  85.     printf("service_port=%u\n", ntohs(service_info->s_port));
  86.     printf("service_protocole='%s'\n", service_info->s_proto);
  87.  
  88.     // Création socket
  89.     if ((sk_dialog=socket(AF_INET, SOCK_DGRAM, 0)) == (-1))
  90.     {
  91.         fprintf(stderr, "ligne %u - socket() - %s\n", __LINE__, sys_errlist[errno]);
  92.         exit(errno);
  93.     }
  94.     printf("Socket créée\n" );
  95.  
  96.     // Remplissage adresse socket
  97.     memset(&adr_serveur, 0, sizeof(struct sockaddr_in));
  98.     adr_serveur.sin_len=host_info->h_length;
  99.     adr_serveur.sin_family=AF_INET;
  100.     adr_serveur.sin_port=service_info->s_port;
  101.     memcpy(&adr_serveur.sin_addr.s_addr, host_info->h_addr, host_info->h_length);
  102.  
  103.     // Saisie et envoi de la chaîne en boucle
  104.     do
  105.     {
  106.         // Saisie de la chaîne
  107.         fputs("Entrer chaine (EOT pour finir) :", stdout); fflush(stdout);
  108.         fflush(stdin); fgets(buf, SZ_BUF, stdin);
  109.  
  110.         // Suppression de la chaîne saisie le caractère '\n' s'il y est
  111.         if ((pt=strchr(buf, '\n')) != NULL)
  112.             *pt='\0';
  113.  
  114.         // Envoi de la chaîne modifiée sur la socket
  115.         if (sendto(sk_dialog, buf, strlen(buf) + 1, 0, &adr_serveur, sizeof(struct sockaddr_in)) == (-1))
  116.             fprintf(stderr, "ligne %u - sendto(%s) - %s\n", __LINE__, buf, sys_errlist[errno]);
  117.     }
  118.     while (strcmp(buf, "EOT" ) != 0);
  119.  
  120.     // Fermeture socket et fin du programme
  121.     close(sk_dialog);
  122.     exit(0);
  123. }


Ici il faudra créer une entrée "toto" en mode "udp" dans "/etc/services" pour que le client et le serveur puissent récupérer un n° de port


Message édité par Sve@r le 12-10-2009 à 21:57:08

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 17-10-2009 à 00:40:14    

Super c'est exatement ces bouts de code que j'avais besoin pour commencer mon projet.
J'ai donc choisi les sockets serveur/client en TCP.
 Par contre quand je compile j'ai des erreurs...j'en ai corrigé une en rajoutant en include stdlib.h mais les erreurs dans le main je n'arrive pas à les corriger.  
Voilà les erreurs que j'ai :
"serveur.c: In function ‘main’:
serveur.c:82: attention : passing argument 2 of ‘bind’ from incompatible pointer type
serveur.c:101: attention : passing argument 2 of ‘accept’ from incompatible pointer type
serveur.c:120:34: attention : trigraphe ??) ignoré, utilisez -trigraphs pour le permettre
serveur.c:126:33: attention : trigraphe ??) ignoré, utilisez -trigraphs pour le permettre
/tmp/ccuGFSZS.o: In function `main':
serveur.c:(.text+0x5e): warning: `sys_errlist' is deprecated; use `strerror' or `strerror_r' instead"
Si quelqu'un peut m'aider !!!
merci à lui...

Reply

Marsh Posté le 17-10-2009 à 00:44:25    

Et pour le client, j'ai le même type d'erreur :
"client.c: In function ‘main’:
client.c:52: attention : incompatible implicit declaration of built-in function ‘exit’
client.c:60: attention : incompatible implicit declaration of built-in function ‘exit’
client.c:80: attention : incompatible implicit declaration of built-in function ‘exit’
client.c:91: erreur: ‘struct sockaddr_in’ has no member named ‘sin_len’
client.c:103: attention : incompatible implicit declaration of built-in function ‘exit’
client.c:107: attention : passing argument 2 of ‘connect’ from incompatible pointer type
client.c:132: attention : incompatible implicit declaration of built-in function ‘exit’"
???

Reply

Marsh Posté le 17-10-2009 à 02:48:42    

J'ai oublié de préciser, je suis sous Ubuntu...

Reply

Marsh Posté le 19-10-2009 à 23:11:03    

Ccabrel a écrit :

J'ai oublié de préciser, je suis sous Ubuntu...


Oui, il y a des trucs qui ont changé depuis que j'ai développé ces exemples
1) pour la fonction exit, faut inclure stdlib.h
2) sys_errlist est devenu déprécié. Faut remplacer sys_errlist[errno] par strerror(errno)
3) sin_len a disparu de la structure sockaddr_in => pas de souci, partout où j'y fais référence tu le supprimes (surtout que je ne m'en sers jamais sauf dans un printf)
 
Quand aux erreurs concernant accept et bind, c'est parce que ces fonctions sont des fonctions générales qui acceptent en entrée des pointeurs vers de simples "struct sockaddr"
Cette attitude permet d'utiliser bind et accept avec des socket unix (utilisant une struct sockaddr_un) ou des socket inet (utilisant une struct sockaddr_in)
Et donc à l'époque, le compilo ne disait rien. Aujourd'hui, il est plus chiant donc faut lui expliquer que tu sais ce que tu fais et quand t'appelles bind() et accept(), tu castes le pointeur passé en "struct sockaddr *"
Tout ça est expliqué dans mon cours sur les socket
 
L'erreur des trigraphs, je vois pas de quoi il s'agit.


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 20-10-2009 à 00:08:33    

merci pour ces 2000 lignes de code, l'erreur est à la ligne 42, colonne 69

Reply

Marsh Posté le 20-10-2009 à 23:31:54    

Taz a écrit :

merci pour ces 2000 lignes de code


Elles ne te sont pas destinées donc je vois pas ce que tu ramènes ton grain de sel
 

Taz a écrit :

l'erreur est à la ligne 42, colonne 69


Povtyp. T'as même pas vu qu'on ne te demande pas d'y trouver quoi que ce soit car les quelques erreurs dues à l'ancienneté du code ont été expliquées et sont facilement rectifiables !!!


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 08-03-2010 à 01:54:00    

merci beaucoup cher Sve@r!!

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed