Compare commits

...

3 Commits
tcp ... master

@ -5,13 +5,4 @@ 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
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
les programmes sont disponibles dans les branches tcp et udp

@ -1,105 +0,0 @@
#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, "getaddrinfo: %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, "Could not connect\n");
exit(EXIT_FAILURE);
}
}
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 */
if (len + 1 > BUF_SIZE) {
fprintf(stderr, "Ignoring long message in argument %d\n", j);
}
if (write(sfd, argtemp, len) != len) {
fprintf(stderr, "partial/failed write\n");
exit(EXIT_FAILURE);
}
nread = read(sfd, buf, BUF_SIZE);
if (nread == -1) {
perror("read");
exit(EXIT_FAILURE);
}
printf("Received %ld bytes: %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, "mettre: %s ip port message\n", argv[0]);
exit(EXIT_FAILURE);
}
char* ip = argv[1];
char* port = argv[2];
char* message = argv[3]; // remplissage des varables a partir des arguments passés au programme
/* Obtain address(es) matching host/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); /* No longer needed */
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 */
sendreceive(argv[j], len, j, sfd);
}
exit(EXIT_SUCCESS);
}

@ -1,103 +0,0 @@
#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, "Could not 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, "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
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