Sve@r | 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 :
#include <sys/types.h> // Types prédéfinis "c" #include <sys/socket.h> // Généralités sockets #include <sys/un.h> // Spécifications socket unix #include <stdio.h> // I/O fichiers classiques #include <signal.h> // Signaux de communication #include <errno.h> // Erreurs système extern const char* const sys_errlist[]; // Liste messages erreurs #define NAME_SOCKET ("socket_file" ) // Nom fichier socket #define SZ_BUF (256) // Taille buffer main( int argc, // Nbre arguments char *argv[]) // Ptr arguments { // Déclaration des variables int sk_creat; // Socket de création int sk_dialog; // Socket de dialogue int pid; // Process créé int sz_read; // Nombre octets lus char buf[SZ_BUF]; // Buffer texte struct sockaddr_un adr_serveur; // Adresse socket serveur // Détournement du signal émis à la mort du fils (il ne reste pas zombie) signal(SIGCHLD, SIG_IGN); // Effacement fichier socket résiduel unlink(NAME_SOCKET); // Création socket if ((sk_creat=socket(AF_UNIX, SOCK_STREAM, 0)) == (-1)) { fprintf(stderr, "ligne %u - socket() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } // Remplissage adresse socket memset(&adr_serveur, 0, sizeof(struct sockaddr_un)); adr_serveur.sun_len=strlen(NAME_SOCKET) + 1; adr_serveur.sun_family=AF_UNIX; memcpy(&(adr_serveur.sun_path), NAME_SOCKET, strlen(NAME_SOCKET)); // Identification socket/réseau if (bind(sk_creat, &adr_serveur, sizeof(struct sockaddr_un)) == (-1)) { fprintf(stderr, "ligne %u - bind() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } // Prise de la ligne listen(sk_creat, 1); // Ecoute permanente fputc('\n', stdout); while (1) { printf("ppid=%u, pid=%u\tAttente entrée...", getppid(), getpid()); fflush(stdout); // Attente connexion client if ((sk_dialog=accept(sk_creat, NULL, NULL)) == (-1)) { fprintf(stderr, "ligne %u - accept() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } fputs("Entrée émise\n", stdout); // Duplication du process switch (pid=fork()) { case (-1): // Erreur de fork close(sk_creat); close(sk_dialog); fprintf(stderr, "ligne %u - fork() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); case 0: // Fils // Fermeture socket inutilisée close(sk_creat); // Lecture en boucle sur la socket while ((sz_read=read(sk_dialog, buf, SZ_BUF)) > 0) { printf("\n\tppid=%u, pid=%u\tLe serveur a lu '%s'%s\n", getppid(), getpid(), buf, strcmp(buf, "EOT" ) != 0 ?"" :"=> Fin de communication" ); // Si la chaine contient "EOT" if (strcmp(buf, "EOT" ) == 0) break; } // Si l'arrêt de la lecture est dû à ne erreur if (sz_read == (-1)) { close(sk_dialog); fprintf(stderr, "ligne %u - read() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } // Fin du fils close(sk_dialog); exit(0); default: // Père close(sk_dialog); } } // Pas de sortie du programme - Boucle infinie // Fermeture socket et fin théorique du programme (pour être propre) close(sk_creat); }
|
Le client
Code :
#include <sys/types.h> // Types prédéfinis "c" #include <sys/socket.h> // Généralités sockets #include <sys/un.h> // Spécifications socket unix #include <stdio.h> // I/O fichiers classiques #include <string.h> // Gestion chaines de caractères #include <errno.h> // Erreurs système extern const char* const sys_errlist[]; // Liste messages erreurs #define NAME_SOCKET ("socket_file" ) // Nom fichier socket #define SZ_BUF (256) // Taille buffer main( int argc, // Nbre arguments char *argv[]) // Ptr arguments { // Déclaration des variables int sk_connect; // Socket de connection int sk_dialog; // Socket de dialogue char buf[SZ_BUF]; // Buffer texte char *pt; // Ptr vers un caractère qcq. struct sockaddr_un adr_serveur; // Adresse socket serveur // Remplissage adresse socket memset(&adr_serveur, 0, sizeof(struct sockaddr_un)); adr_serveur.sun_len=strlen(NAME_SOCKET) + 1; adr_serveur.sun_family=AF_UNIX; memcpy(&adr_serveur.sun_path, NAME_SOCKET, strlen(NAME_SOCKET)); // Tentative de connection en boucle permanente fputc('\n', stdout); do { // Création socket if ((sk_dialog=socket(AF_UNIX, SOCK_STREAM, 0)) == (-1)) { fprintf(stderr, "ligne %u - socket() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } // Connection au serveur if ((sk_connect=connect(sk_dialog, &adr_serveur, sizeof(struct sockaddr_un))) == (-1)) { fprintf(stderr, "ligne %u - connect() - %s\n", __LINE__, sys_errlist[errno]); sleep(5); } } while (sk_connect == (-1)); printf("Connection réussie\n" ); // Saisie et envoi de la chaîne en boucle do { // Saisie de la chaîne fputs("Entrer chaine (EOT pour finir) :", stdout); fflush(stdout); fflush(stdin); fgets(buf, SZ_BUF, stdin); // Suppression de la chaîne saisie le caractère '\n' s'il y est if ((pt=strchr(buf, '\n')) != NULL) *pt='\0'; // Envoi de la chaîne modifiée sur la socket if (write(sk_dialog, buf, strlen(buf) + 1) == (-1)) fprintf(stderr, "ligne %u - write(%s) - %s\n", __LINE__, buf, sys_errlist[errno]); } while (strcmp(buf, "EOT" ) != 0); // Fermeture socket et fin du programme close(sk_dialog); }
|
Exemple2: communication en tcp. Le serveur
Code :
#include <sys/types.h> // Types prédéfinis "c" #include <sys/socket.h> // Généralités sockets #include <sys/param.h> // Paramètres et limites système #include <netinet/in.h> // Spécifications socket internet #include <arpa/inet.h> // Adresses format "arpanet" #include <signal.h> // Signaux de communication #include <stdio.h> // I/O fichiers classiques #include <netdb.h> // Gestion network database #include <errno.h> // Erreurs système extern const char* const sys_errlist[]; // Liste messages erreurs #define SERVICE_LABEL ("toto" ) // Nom service requis #define SERVICE_PROTOCOL ("tcp" ) // Protocole service requis #define SZ_BUF (256) // Taille buffer main( int argc, // Nbre arguments char *argv[]) // Ptr arguments { // Déclaration des variables ushort i; // Indice de boucle ushort j; // Indice de boucle int sk_creat; // Socket de création int sk_dialog; // Socket de dialogue int pid; // Process créé int len_adr; // Taille adresse int sz_read; // Nbre octets lus char buf[SZ_BUF]; // Buffer texte char hostname[MAXHOSTNAMELEN + 1]; // Nom machine locale struct sockaddr_in adr_serveur; // Adresse socket serveur struct sockaddr_in adr_client; // Adresse socket client struct hostent *host_info; // Info. host client connecté struct servent *service_info; // Info. service demandé char *adr_ascii; // Adresse client mode ascii // Détournement du signal émis à la mort du fils (il ne reste pas zombie) signal(SIGCHLD, SIG_IGN); // Récuperation nom machine locale (juste pour l'exemple) if (gethostname(hostname, MAXHOSTNAMELEN) != 0) { fprintf(stderr, "ligne %u - gethostname(%s) - %s\n", __LINE__, hostname, sys_errlist[errno]); exit(errno); } printf("gethostname='%s'\n", hostname); // Récuperation port dans "/etc/services" if ((service_info=getservbyname(SERVICE_LABEL, SERVICE_PROTOCOL)) == NULL) { fprintf(stderr, "ligne %u - getservbyname(%s, %s) - %s\n", __LINE__, SERVICE_LABEL, SERVICE_PROTOCOL, sys_errlist[errno]); exit(errno); } fputc('\n', stdout); printf("service_name='%s'\n", service_info->s_name); for (i=0; service_info->s_aliases[i] != NULL; i++) printf("service_s_aliase[%hu]='%s'\n", i, service_info->s_aliases[i]); printf("service_port=%u\n", ntohs(service_info->s_port)); printf("service_protocole='%s'\n", service_info->s_proto); // Création socket if ((sk_creat=socket(AF_INET, SOCK_STREAM, 0)) == (-1)) { fprintf(stderr, "ligne %u - socket() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } printf("Socket créée\n" ); // Remplissage adresse socket memset(&adr_serveur, 0, sizeof(struct sockaddr_in)); adr_serveur.sin_family=AF_INET; adr_serveur.sin_port=service_info->s_port; adr_serveur.sin_addr.s_addr=INADDR_ANY; // Identification socket/réseau if (bind(sk_creat, &adr_serveur, sizeof(struct sockaddr_in)) == (-1)) { fprintf(stderr, "ligne %u - bind() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } printf("Socket connectée au réseau\n" ); // Ecoute de la ligne listen(sk_creat, 1); // Attente permanente fputc('\n', stdout); while (1) { printf("ppid=%u, pid=%u\tAttente entrée...", getppid(), getpid()); fflush(stdout); // Attente connexion client len_adr=sizeof(struct sockaddr_in); if ((sk_dialog=accept(sk_creat, &adr_client, &len_adr)) == (-1)) { fprintf(stderr, "ligne %u - accept() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } // Client connecté fputs("Entrée émise ", stdout); // Transformation adresse net en ascii if ((adr_ascii=inet_ntoa(adr_client.sin_addr)) > (char*)0) { printf("(adr=%s", adr_ascii); // Récupération informations sur client par son adresse if ((host_info=gethostbyaddr((char*)&adr_client.sin_addr.s_addr, sizeof(struct in_addr), AF_INET)) != NULL) printf(" - %s)\n", host_info->h_name); else { fputs("- ???)\n", stdout); fprintf(stderr, "ligne %u - gethostbyaddr() - %s\n", __LINE__, sys_errlist[errno]); } } else { fputs("(adr=???)\n", stdout); fprintf(stderr, "ligne %u - inet_ntoa() - %s\n", __LINE__, sys_errlist[errno]); } // Duplication du process switch (pid=fork()) { case (-1): // Erreur de fork close(sk_creat); close(sk_dialog); fprintf(stderr, "ligne %u - fork() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); case 0: // Fils // Fermeture socket inutilisée close(sk_creat); // Lecture en boucle sur la socket while ((sz_read=read(sk_dialog, buf, SZ_BUF)) > 0) { printf("\n\tppid=%u, pid=%u\tLe serveur a lu '%s'%s\n", getppid(), getpid(), buf, strcmp(buf, "EOT" ) != 0 ?"" :"=> Fin de communication" ); // Si la chaine contient "EOT" if (strcmp(buf, "EOT" ) == 0) break; } // Si l'arrêt de la lecture est dû à une erreur if (sz_read == (-1)) { close(sk_dialog); fprintf(stderr, "ligne %u - read() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } // Fin du fils close(sk_dialog); exit(0); default: // Père close(sk_dialog); } } // Pas de sortie de programme - Boucle infinie // Fermeture socket et fin théorique du programme (pour être propre) close(sk_creat); }
|
Le client
Code :
#include <sys/types.h> // Types prédéfinis "c" #include <sys/socket.h> // Généralités sockets #include <sys/param.h> // Paramètres et limites système #include <netinet/in.h> // Spécifications socket internet #include <stdio.h> // I/O fichiers classiques #include <string.h> // Gestion chaines de caractères #include <netdb.h> // Gestion network database #include <errno.h> // Erreurs système extern const char* const sys_errlist[]; // Liste messages erreurs #define SERVEUR_DEFAULT ("localhost" ) // Nom serveur utilisé par défaut #define SERVICE_LABEL ("toto" ) // Nom service requis #define SERVICE_PROTOCOL ("tcp" ) // Protocole service requis #define SZ_BUF (256) // Taille buffer main( int argc, // Nbre arguments char *argv[]) // Ptr arguments { // Déclaration des variables ushort i; // Indice de boucle ushort j; // Indice de boucle int sk_connect; // Socket de connection int sk_dialog; // Socket de dialogue char buf[SZ_BUF]; // Buffer texte char hostname[MAXHOSTNAMELEN + 1]; // Nom machine locale char *serveur; // Ptr vers le nom du serveur char *pt; // Ptr vers un caractère qcq. struct sockaddr_in adr_serveur; // Adresse socket serveur struct hostent *host_info; // Info. host struct servent *service_info; // Info. service demandé // Remplissage du nom du serveur if (argc > 1) // Le nom du serveur est l'argument n° 1 serveur=argv[1]; else { // Le nom du serveur est pris par défaut serveur=SERVEUR_DEFAULT; printf("Pas d'argument pour %s - Utilisation de %s\n", *argv, SERVEUR_DEFAULT); } // Récuperation nom machine locale (juste pour l'exemple) if (gethostname(hostname, MAXHOSTNAMELEN) != 0) { fprintf(stderr, "ligne %u - gethostname(%s) - %s\n", __LINE__, hostname, sys_errlist[errno]); exit(errno); } printf("gethostname='%s'\n", hostname); // Récuperation informations serveur if ((host_info=gethostbyname(serveur)) == NULL) { fprintf(stderr, "ligne %u - gethostbyname(%s) - %s\n", __LINE__, serveur, sys_errlist[errno]); exit(errno); } fputc('\n', stdout); printf("host_info.h_name='%s'\n", host_info->h_name); for (i=0; host_info->h_aliases[i] != NULL; i++) printf("host_info.h_aliase[%hu]='%s'\n", i, host_info->h_aliases[i]); printf("host_info.h_addrtype=%u\n", host_info->h_addrtype); printf("host_info.h_length=%u\n", host_info->h_length); for (i=0; host_info->h_addr_list[i] != NULL; i++) { printf("host_info.h_addr_list[%hu]=", i); for (j=0; j < host_info->h_length; j++) printf("%hu ", (unsigned char)host_info->h_addr_list[i][j]); fputc('\n', stdout); } // Récuperation port dans "/etc/services" if ((service_info=getservbyname(SERVICE_LABEL, SERVICE_PROTOCOL)) ==NULL) { fprintf(stderr, "ligne %u - getservbyname(%s, %s) - %s\n", __LINE__, SERVICE_LABEL, SERVICE_PROTOCOL, sys_errlist[errno]); exit(errno); } fputc('\n', stdout); printf("service_name='%s'\n", service_info->s_name); for (i=0; service_info->s_aliases[i] != NULL; i++) printf("service_s_aliase[%hu]='%s'\n", i, service_info->s_aliases[i]); printf("service_port=%u\n", ntohs(service_info->s_port)); printf("service_protocole='%s'\n", service_info->s_proto); // Remplissage adresse socket memset(&adr_serveur, 0, sizeof(struct sockaddr_in)); adr_serveur.sin_len=host_info->h_length; adr_serveur.sin_family=AF_INET; adr_serveur.sin_port=service_info->s_port; memcpy(&adr_serveur.sin_addr.s_addr, host_info->h_addr, host_info->h_length); // Tentative de connection en boucle permanente fputc('\n', stdout); do { // Création socket if ((sk_dialog=socket(AF_INET, SOCK_STREAM, 0)) == (-1)) { fprintf(stderr, "ligne %u - socket() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } // Connection au serveur if ((sk_connect=connect(sk_dialog, &adr_serveur, sizeof(struct sockaddr_in))) == (-1)) { fprintf(stderr, "ligne %u - connect() - %s\n", __LINE__, sys_errlist[errno]); sleep(5); } } while (sk_connect == (-1)); printf("Connection réussie\n" ); // Saisie et envoi de la chaîne en boucle do { // Saisie de la chaîne fputs("Entrer chaine (EOT pour finir) :", stdout); fflush(stdout); fflush(stdin); fgets(buf, SZ_BUF, stdin); // Suppression de la chaîne saisie le caractère '\n' s'il y est if ((pt=strchr(buf, '\n')) != NULL) *pt='\0'; // Envoi de la chaîne modifiée sur la socket if (write(sk_dialog, buf, strlen(buf) + 1) == (-1)) fprintf(stderr, "ligne %u - write(%s) - %s\n", __LINE__, buf, sys_errlist[errno]); } while (strcmp(buf, "EOT" ) != 0); // Fermeture socket et fin du programme close(sk_dialog); exit(0); }
|
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 :
#include <sys/types.h> // Types prédéfinis "c" #include <sys/socket.h> // Généralités sockets #include <sys/param.h> // Paramètres et limites système #include <netinet/in.h> // Spécifications socket internet #include <arpa/inet.h> // Adresses format "arpanet" #include <stdio.h> // I/O fichiers classiques #include <netdb.h> // Gestion network database #include <errno.h> // Erreurs système extern const char* const sys_errlist[]; // Liste messages erreurs #define SERVICE_LABEL ("toto" ) // Nom service requis #define SERVICE_PROTOCOL ("udp" ) // Protocole service requis #define SZ_BUF (256) // Taille buffer main( int argc, // Nbre arguments char *argv[]) // Ptr arguments { // Déclaration des variables ushort i; // Indice de boucle ushort j; // Indice de boucle int sk_dialog; // Socket de dialogue int len_adr; // Taille adresse char buf[SZ_BUF]; // Buffer texte char hostname[MAXHOSTNAMELEN + 1]; // Nom machine locale struct sockaddr_in adr_serveur; // Adresse socket serveur struct sockaddr_in adr_client; // Adresse socket client struct hostent *host_info; // Info. host client connecté struct servent *service_info; // Info. service demandé char *adr_ascii; // Adresse client mode ascii // Récuperation nom machine locale (juste pour l'exemple) if (gethostname(hostname, MAXHOSTNAMELEN) != 0) { fprintf(stderr, "ligne %u - gethostname(%s) - %s\n", __LINE__, hostname, sys_errlist[errno]); exit(errno); } printf("gethostname='%s'\n", hostname); // Récuperation port dans "/etc/services" if ((service_info=getservbyname(SERVICE_LABEL, SERVICE_PROTOCOL)) == NULL) { fprintf(stderr, "ligne %u - getservbyname(%s, %s) - %s\n", __LINE__, SERVICE_LABEL, SERVICE_PROTOCOL, sys_errlist[errno]); exit(errno); } fputc('\n', stdout); printf("service_name='%s'\n", service_info->s_name); for (i=0; service_info->s_aliases[i] != NULL; i++) printf("service_s_aliase[%hu]='%s'\n", i, service_info->s_aliases[i]); printf("service_port=%u\n", ntohs(service_info->s_port)); printf("service_protocole='%s'\n", service_info->s_proto); // Création socket if ((sk_dialog=socket(AF_INET, SOCK_DGRAM, 0)) == (-1)) { fprintf(stderr, "ligne %u - socket() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } fputs("Socket créée\n", stdout); // Remplissage adresse socket memset(&adr_serveur, 0, sizeof(struct sockaddr_in)); adr_serveur.sin_family=AF_INET; adr_serveur.sin_port=service_info->s_port; adr_serveur.sin_addr.s_addr=INADDR_ANY; // Identification socket/réseau if (bind(sk_dialog, &adr_serveur, sizeof(struct sockaddr_in)) == (-1)) { fprintf(stderr, "ligne %u - bind() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } fputs("Socket reliée au réseau\n", stdout); // Lecture en boucle sur la socket len_adr=sizeof(struct sockaddr_in); while (1) { if (recvfrom(sk_dialog, buf, SZ_BUF, 0, &adr_client, &len_adr) == (-1)) fprintf(stderr, "ligne %u - recvfrom() - %s\n", __LINE__, sys_errlist[errno]); // Transformation adresse client en ascii if ((adr_ascii=inet_ntoa(adr_client.sin_addr)) > (char*)0) { printf("From client %s ", adr_ascii); // Récupération informations sur client par son adresse if ((host_info=gethostbyaddr((char*)&adr_client.sin_addr.s_addr, sizeof(struct in_addr), AF_INET)) != NULL) printf("(%s)", host_info->h_name); else { fputs("(???)", stdout); fprintf(stderr, "ligne %u - gethostbyaddr() - %s\n", __LINE__, sys_errlist[errno]); } } else { fputs("From client ???", stdout); fprintf(stderr, "ligne %u - inet_ntoa() - %s\n", __LINE__, sys_errlist[errno]); } printf(" - Le serveur a lu '%s'%s\n", buf, strcmp(buf, "EOT" ) != 0 ?"" :"=> Fin de communication" ); } // Pas de sortie de programme - Boucle infinie // Fermeture socket et fin théorique du programme (pour être propre) close(sk_dialog); exit(0); }
|
Le client
Code :
#include <sys/types.h> // Types prédéfinis "c" #include <sys/socket.h> // Généralités sockets #include <sys/param.h> // Paramètres et limites système #include <netinet/in.h> // Spécifications socket internet #include <stdio.h> // I/O fichiers classiques #include <string.h> // Gestion chaines de caractères #include <netdb.h> // Gestion network database #include <errno.h> // Erreurs système extern const char* const sys_errlist[]; // Liste messages erreurs #define SERVEUR_DEFAULT ("localhost" ) // Nom serveur utilisé par défaut #define SERVICE_LABEL ("toto" ) // Nom service requis #define SERVICE_PROTOCOL ("udp" ) // Protocole service requis #define SZ_BUF (256) // Taille buffer main( int argc, // Nbre arguments char *argv[]) // Ptr arguments { // Déclaration des variables ushort i; // Indice de boucle ushort j; // Indice de boucle int sk_dialog; // Socket de dialogue char buf[SZ_BUF]; // Buffer texte char hostname[MAXHOSTNAMELEN + 1]; // Nom machine locale char *pt; // Ptr vers un caractère qcq. char *serveur; // Ptr vers le nom du serveur struct sockaddr_in adr_serveur; // Adresse socket serveur struct hostent *host_info; // Info. host struct servent *service_info; // Info. service demandé // Remplissage du nom du serveur if (argc > 1) // Le nom du serveur est l'argument n° 1 serveur=argv[1]; else { // Le nom du serveur est pris par défaut serveur=SERVEUR_DEFAULT; printf("Pas d'argument pour %s - Utilisation de %s\n", *argv, serveur); } // Récuperation nom machine locale (juste pour l'exemple) if (gethostname(hostname, MAXHOSTNAMELEN) != 0) { fprintf(stderr, "ligne %u - gethostname(%s) - %s\n", __LINE__, hostname, sys_errlist[errno]); exit(errno); } printf("gethostname='%s'\n", hostname); // Récuperation informations serveur if ((host_info=gethostbyname(serveur)) == NULL) { fprintf(stderr, "ligne %u - gethostbyname(%s) - %s\n", __LINE__, serveur, sys_errlist[errno]); exit(errno); } fputc('\n', stdout); printf("host_info.h_name='%s'\n", host_info->h_name); for (i=0; host_info->h_aliases[i] != NULL; i++) printf("host_info.h_aliase[%hu]='%s'\n", i, host_info->h_aliases[i]); printf("host_info.h_addrtype=%u\n", host_info->h_addrtype); printf("host_info.h_length=%u\n", host_info->h_length); for (i=0; host_info->h_addr_list[i] != NULL; i++) { printf("host_info.h_addr_list[%hu]=", i); for (j=0; j < host_info->h_length; j++) printf("%hu ", (unsigned char)host_info->h_addr_list[i][j]); fputc('\n', stdout); } // Récuperation port dans "/etc/services" if ((service_info=getservbyname(SERVICE_LABEL, SERVICE_PROTOCOL)) == NULL) { fprintf(stderr, "ligne %u - getservbyname(%s, %s) - %s\n", __LINE__, SERVICE_LABEL, SERVICE_PROTOCOL, sys_errlist[errno]); exit(errno); } fputc('\n', stdout); printf("service_name='%s'\n", service_info->s_name); for (i=0; service_info->s_aliases[i] != NULL; i++) printf("service_s_aliase[%hu]='%s'\n", i, service_info->s_aliases[i]); printf("service_port=%u\n", ntohs(service_info->s_port)); printf("service_protocole='%s'\n", service_info->s_proto); // Création socket if ((sk_dialog=socket(AF_INET, SOCK_DGRAM, 0)) == (-1)) { fprintf(stderr, "ligne %u - socket() - %s\n", __LINE__, sys_errlist[errno]); exit(errno); } printf("Socket créée\n" ); // Remplissage adresse socket memset(&adr_serveur, 0, sizeof(struct sockaddr_in)); adr_serveur.sin_len=host_info->h_length; adr_serveur.sin_family=AF_INET; adr_serveur.sin_port=service_info->s_port; memcpy(&adr_serveur.sin_addr.s_addr, host_info->h_addr, host_info->h_length); // Saisie et envoi de la chaîne en boucle do { // Saisie de la chaîne fputs("Entrer chaine (EOT pour finir) :", stdout); fflush(stdout); fflush(stdin); fgets(buf, SZ_BUF, stdin); // Suppression de la chaîne saisie le caractère '\n' s'il y est if ((pt=strchr(buf, '\n')) != NULL) *pt='\0'; // Envoi de la chaîne modifiée sur la socket if (sendto(sk_dialog, buf, strlen(buf) + 1, 0, &adr_serveur, sizeof(struct sockaddr_in)) == (-1)) fprintf(stderr, "ligne %u - sendto(%s) - %s\n", __LINE__, buf, sys_errlist[errno]); } while (strcmp(buf, "EOT" ) != 0); // Fermeture socket et fin du programme close(sk_dialog); exit(0); }
|
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.
|