g fini
g fini
Hum.
A mon avis, tu devrais d'or et déjà te mettre à étudier, personne ici ne va faire ton TP à ta place (qui plus est, n'est pas des moindres).
Ce n'est pas méchament que je dis ça, en fait, personne ne te ferais un service de te fournir un logiciel complètement programmé.
De plus, ton sujet comporte bien des domaines d'études:
Couche réseau
Analyse et étude d'un protocol adapté
Analyse et étude d'une base de donnée
Un GUI côté client ?
Tout ça veut dire qu'il faut une intéropérabilité entre ces composants, et encore une fois le faire à ta place ne te ferait aucun bien, tu ne comprendrais strictement pas comment ces composants s'imbriquent.
Bref, achètes toi quelques bouquins ou dit à ton prof que tu n'as jamais suivi de cours de programmation et vois si tu peux pas avoir des cours en plus.
Parce que mine de rien, analyste programmeur c'est 3 ans d'études à temps plein.
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 cpp : 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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 #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 cpp : 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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 #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 cpp : 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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171 #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
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
Code cpp : 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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133 #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); }
Exemple3: communication en udp
Le serveur
Code cpp : 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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 #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
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
Code cpp : 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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 #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); }
Mon Tutoriel sur la programmation «Python»
Mon Tutoriel sur la programmation «Shell»
Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
Et on poste ses codes entre balises [code] et [/code]
Partager