Compare commits

..

4 Commits
master ... udp

Author SHA1 Message Date
Flavien Haas acf663ddac Supprimer 'TP3_sockets_echo-2.pdf' 5 years ago
Flavien Haas 63517aa232 updated readme 5 years ago
Flavien Haas 963c65d630 updated readme 5 years ago
Flavien Haas 4969efda31 maj commentaires 5 years ago

@ -1,8 +1,4 @@
_**But du TP :**_ Utilisation des sockets en mode datagramme et en mode connecté.
_**But du TP :**_ Utilisation des sockets en mode datagramme
Pour ce TP nous réaliserons
- 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
les programmes sont disponibles dans les branches tcp et udp
- 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
- 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

Binary file not shown.

@ -0,0 +1,104 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUF_SIZE 500
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, "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 */
/* 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 , 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 */
}
close(*sfd);
}
if (rp == NULL) { /* Aucune adresse n'a pu marcher */
fprintf(stderr, "N'a pu se connecter\n");
exit(EXIT_FAILURE);
}
}
void sendreceive(char* argtemp, size_t len, int j, int sfd){
char buf[BUF_SIZE];
ssize_t nread;
/* Envoie les arguments restant comme
datagrammes, et lit la réponse du serveur */
if (len + 1 > BUF_SIZE) {
fprintf(stderr, "Long message ignoré %d\n", j);
}
if (write(sfd, argtemp, len) != len) {
fprintf(stderr, "écriture partiel ou échue\n");
exit(EXIT_FAILURE);
}
nread = read(sfd, buf, BUF_SIZE);
if (nread == -1) {
perror("read");
exit(EXIT_FAILURE);
}
printf("Recu %ld octets: %s\n", (long) nread, buf);
}
int main(int argc, char *argv[]) {
struct addrinfo hints;
int sfd, s, j;
size_t len;
char* argtemp;
if (argc < 3) { /* vérification du nombre d'arguments rentrés */
fprintf(stderr, "Usage: %s ip port message\n", argv[0]);
exit(EXIT_FAILURE);
}
/* remplissage des varables a partir des arguments passés au programme */
char* ip = argv[1];
char* port = argv[2];
char* message = argv[3];
/* 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 */
s = cree_socket(ip, port, hints); /* création du socket */
if(s == 1) {
exit(EXIT_FAILURE);
}
con_serveur(&sfd);
freeaddrinfo(result); /* libère la structure d'adresse serveur */
for (j = 3; j < argc; j++) { /* récupère les mots passés en arguments */
len = strlen(argv[j]) + 1;
argtemp = argv[j];
/* +1 pour l'octet null de fin de ligne */
sendreceive(argv[j], len, j, sfd);
}
exit(EXIT_SUCCESS);
}

@ -0,0 +1,100 @@
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netdb.h>
#define BUF_SIZE 500
struct addrinfo *result; /* tableau des adresses réseaux des clients */
int 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;
}
return s;
}
void con_client(int *sfd){
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 */
*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 */
}
close(*sfd);
}
if (rp == NULL) { /* Aucune adresse n'a pu marcher */
fprintf(stderr, "Erreur de bind\n");
exit(EXIT_FAILURE);
}
}
void traite_connexion(int sfd, int s){
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 */
for (;;) {
peer_addr_len = sizeof(struct sockaddr_storage);
nread = recvfrom(sfd, buf, BUF_SIZE, 0, (struct sockaddr *) &peer_addr, &peer_addr_len);
if (nread == -1){
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);
}
else{
fprintf(stderr, "erreur sur l'addresse client %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 */
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 */
/* 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 */
traite_connexion(sfd, s);
}
Loading…
Cancel
Save