Compare commits

...

9 Commits
master ... tcp

Author SHA1 Message Date
Flavien Haas 7bf766ee8f Supprimer 'TP3_sockets_echo-2.pdf' 5 years ago
Flavien Haas 47a42b7067 Supprimer 'Makefile' 5 years ago
Flavien Haas 07263fa737 updated readme 5 years ago
Flavien Haas 7698861b2a maj commentaires 5 years ago
Flavien Haas bfeae0a65c commentaires changés 5 years ago
Flavien Haas d0f3046bf5 clean code 5 years ago
Flavien Haas d52563a834 fonction traite_connexion 5 years ago
Flavien Haas 8aecd5e4a8 added makefile 5 years ago
Flavien Haas a32d94d037 cassé mais connexion ok 5 years ago

BIN
.DS_Store vendored

Binary file not shown.

@ -1,17 +1,4 @@
_**But du TP :**_ Utilisation des sockets en mode datagramme et en mode connecté.
Pour ce TP nous réaliserons
_**But du TP :**_ Utilisation des sockets en mode connecté
- un programme serveur_echo qui prend en paramètre le numéro de port sur lequel est offert le service et renvoie la chaîne reçue en écho au client
- un programme client_echo qui prend le nom de lhôte du serveur (ou son adresse IP) ainsi que son numéro de port, saisit une chaîne de caractères, la renvoie au serveur et affiche lécho reçu par le serveur
Exercice 1 : Ecrire les programmes en mode datagramme
Exercice 2 : Ecrire les programmes en mode connecté
Exercice 3 : Tester vos programmes serveur avec le programme Telnet
Exercice 4 : Modifier vos programmes en mode connecté :
- client pour quil prend la chaîne (à renvoyer en echo) en ligne de commande
- serveur pour quil affiche ladresse IP et le nom de lhôte client

Binary file not shown.

@ -8,37 +8,37 @@
#define BUF_SIZE 500
struct addrinfo *result; // tableau des adresses réseaux des serveurs
struct addrinfo *result; /* tableau des adresses réseaux des serveurs */
int cree_socket(char* ip, char* port, struct addrinfo hints){
int s = getaddrinfo(ip, port, &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
fprintf(stderr, "erreur sur l'addresse serveur %s\n", gai_strerror(s));
s = 1;
}
return s;
}
void con_serveur(int *sfd){
struct addrinfo *rp; // structure de l'adresse du client
struct addrinfo *rp; /* structure de l'adresse du client */
/* getaddrinfo () retourne une liste de structures d'adresses.
Essayez chaque adresse jusqu'à ce que nous ayons réussi à bind(2).
Si socket() (ou bind()) échoue, nous (fermons le socket et)
Essayez chaque adresse jusqu'à ce que nous ayons réussi à connect(2).
Si socket() (ou connect()) échoue, nous (fermons le socket et)
essayons l'adresse suivante */
for (rp = result; rp != NULL; rp = rp->ai_next) {
// socket crée un point de communication et renvoie un descripteur , sfd = socket file descriptor
/* socket crée un point de communication et renvoie un descripteur , sfd = socket file descriptor */
*sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (*sfd == -1){
continue;
}
if (connect(*sfd, rp->ai_addr, rp->ai_addrlen) != 1){
break; // Succès
break; /* Succès */
}
close(*sfd);
}
if (rp == NULL) { // Aucune adresse n'a pu marcher
fprintf(stderr, "Could not connect\n");
if (rp == NULL) { /* Aucune adresse n'a pu marcher */
fprintf(stderr, "N'a pu se connecter");
exit(EXIT_FAILURE);
}
}
@ -46,13 +46,12 @@ void con_serveur(int *sfd){
void sendreceive(char* argtemp, size_t len, int j, int sfd){
char buf[BUF_SIZE];
ssize_t nread;
/* Send remaining command-line arguments as separate
datagrams, and read responses from server */
/* Envoie les derniers arguments et lit la réponse du serveur */
if (len + 1 > BUF_SIZE) {
fprintf(stderr, "Ignoring long message in argument %d\n", j);
fprintf(stderr, "Long message ignoré %d\n", j);
}
if (write(sfd, argtemp, len) != len) {
fprintf(stderr, "partial/failed write\n");
fprintf(stderr, "écriture partiel ou échue\n");
exit(EXIT_FAILURE);
}
nread = read(sfd, buf, BUF_SIZE);
@ -60,7 +59,7 @@ void sendreceive(char* argtemp, size_t len, int j, int sfd){
perror("read");
exit(EXIT_FAILURE);
}
printf("Received %ld bytes: %s\n", (long) nread, buf);
printf("Recu %ld octets: %s\n", (long) nread, buf);
}
int main(int argc, char *argv[]) {
@ -69,37 +68,36 @@ int main(int argc, char *argv[]) {
size_t len;
char* argtemp;
if (argc < 3) { // vérification du nombre d'arguments rentrés
if (argc < 3) { /* vérification du nombre d'arguments rentrés */
fprintf(stderr, "mettre: %s ip port message\n", argv[0]);
exit(EXIT_FAILURE);
}
/* remplissage des variables a partir des arguments passés au programme */
char* ip = argv[1];
char* port = argv[2];
char* message = argv[3]; // remplissage des varables a partir des arguments passés au programme
char* message = argv[3];
/* Obtain address(es) matching host/port */
/* Obtient des adresses avec hote:port */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; // utilisation du serveur sur IPv4/v6 (AF_INET/AF_INET6)
hints.ai_socktype = SOCK_DGRAM; // socket en mode datagramme
hints.ai_family = AF_UNSPEC; /* utilisation du serveur sur IPv4/v6 (AF_INET/AF_INET6)*/
hints.ai_socktype = SOCK_STREAM; /* socket en mode datagramme */
s = cree_socket(ip, port, hints); // création du socket
s = cree_socket(ip, port, hints); /* création du socket */
if(s == 1) {
exit(EXIT_FAILURE);
}
con_serveur(&sfd);
freeaddrinfo(result); /* No longer needed */
freeaddrinfo(result); /* libère la structure d'adresse serveur */
for (j = 3; j < argc; j++) { // récupère les mots passés en arguments
for (j = 3; j < argc; j++) { /* récupère les mots passés en arguments */
len = strlen(argv[j]) + 1;
argtemp = argv[j];
/* +1 for terminating null byte */
/* +1 pour l'octet null de finde ligne */
sendreceive(argv[j], len, j, sfd);
}
exit(EXIT_SUCCESS);
}

@ -7,97 +7,98 @@
#include <netdb.h>
#define BUF_SIZE 500
#define MAX_CON 5 /* nombre maximum de connexions */
struct addrinfo *result; // tableau des adresses réseaux des clients
struct addrinfo *result; /* tableau des adresses réseaux des clients */
int cree_socket(struct addrinfo hints, char* port){
void cree_socket(struct addrinfo hints, char* port){
int s = getaddrinfo(NULL, port, &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
s = 1;
exit(EXIT_FAILURE);
}
return s;
}
void con_client(int *sfd){
struct addrinfo *rp; // structure de l'adresse du client
struct addrinfo *rp; /* structure de l'adresse du client */
/* getaddrinfo () retourne une liste de structures d'adresses.
Essayez chaque adresse jusqu'à ce que nous ayons réussi à bind(2).
Si socket() (ou bind()) échoue, nous (fermons le socket et)
essayons l'adresse suivante */
for (rp = result; rp != NULL; rp = rp->ai_next) {
// socket crée un point de communication et renvoie un descripteur
/* socket crée un point de communication et renvoie un descripteur */
*sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (*sfd == -1){
continue;
}
if (bind(*sfd, rp->ai_addr, rp->ai_addrlen) == 0){
break; // Succès
break; /* Succès */
}
close(*sfd);
}
if (rp == NULL) { // Aucune adresse n'a pu marcher
fprintf(stderr, "Could not bind\n");
if (rp == NULL) { /* Aucune adresse n'a pu marcher */
fprintf(stderr, "Could not connect\n");
exit(EXIT_FAILURE);
}
if (listen(*sfd, MAX_CON) == -1){
fprintf(stderr, "erreur du listen");
exit(EXIT_FAILURE);
}
freeaddrinfo(result); /* libère la structure d'adresse client */
}
void traite_connexion(int sfd, int s){
void traite_connexion(int *sfd){
ssize_t nread;
char buf[BUF_SIZE];
struct sockaddr_storage peer_addr;
socklen_t peer_addr_len;
// Lit les datagrammes et les renvoi au client
int s, new_sfd;
char host[NI_MAXHOST], service[NI_MAXSERV];
/* Lit les messages et les renvoi au client */
for (;;) {
peer_addr_len = sizeof(struct sockaddr_storage);
nread = recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *) &peer_addr, &peer_addr_len);
new_sfd = accept(*sfd, (struct sockaddr*) &peer_addr, &peer_addr_len); /* accepte la connexion */
nread = read(new_sfd, buf, BUF_SIZE); /* lit dans le buffer de la connexion, renvoie la taille du message */
if (nread == -1){
continue;
/* ignore la mauvaise requete */
continue; /* ignore la mauvaise requete */
}
char host[NI_MAXHOST], service[NI_MAXSERV];
s = getnameinfo((struct sockaddr *) &peer_addr, peer_addr_len, host, NI_MAXHOST, service, NI_MAXSERV, NI_NUMERICSERV);
if (s == 0){
printf("Recu %ld octets de %s:%s\n", (long) nread, host, service);
if (write(new_sfd, buf, nread) != nread){
fprintf(stderr, "Erreur d'envoi de la reponse\n");
}
close(new_sfd); /* ferme la connexion */
}
else{
fprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));
}
if (sendto(sfd, buf, nread, 0, (struct sockaddr *) &peer_addr, peer_addr_len) != nread){
fprintf(stderr, "Erreur d'envoi de la reponse\n");
}
}
}
int main(int argc, char *argv[]){
struct addrinfo hints;
int s; // s code de retour de getaddrinfo
int sfd; // code de retour de l'ouverture du socket
int s; /* s code de retour de getaddrinfo */
int sfd; /* code de retour de l'ouverture du socket */
if (argc != 2) { // test du nombre d'arguments entrés
if (argc != 2) { /* test du nombre d'arguments entrés */
fprintf(stderr, "Usage: %s port\n", argv[0]);
exit(EXIT_FAILURE);
}
char* port = argv[1]; // récupération du port passée en paramètre du programme
char* port = argv[1]; /* récupération du port passée en paramètre du programme */
// remplissage de la structure hints contenants la configuration réseau du serveur
/* remplissage de la structure hints contenants la configuration réseau du serveur */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; // utilisation du serveur sur IPv4/v6 (AF_INET/AF_INET6)
hints.ai_socktype = SOCK_DGRAM; // socket en mode datagramme
s = cree_socket(hints, port); // création du socket
if(s == 1) {
exit(EXIT_FAILURE);
}
con_client(&sfd);
freeaddrinfo(result); // libère la structure d'adresse client
hints.ai_family = AF_UNSPEC; /* utilisation du serveur sur IPv4/v6 (AF_INET/AF_INET6) */
hints.ai_socktype = SOCK_STREAM; /* socket en mode datagramme */
hints.ai_protocol = IPPROTO_TCP; /* protocol de connexion */
traite_connexion(sfd, s);
cree_socket(hints, port); /* création du socket */
con_client(&sfd); /* connexion au client */
traite_connexion(&sfd);
}

Loading…
Cancel
Save