Compare commits

..

No commits in common. "master" and "refactore" have entirely different histories.

8 changed files with 227 additions and 819 deletions

Binary file not shown.

View file

@ -63,25 +63,11 @@ Example usage of v3 :
./t_sockv3 -s -l 15 localhost 4000 # sender ./t_sockv3 -s -l 15 localhost 4000 # sender
``` ```
Example usage of v4 :
```
./t_sockv4 -S -r -n 20 -l 15 4000 # server receiver
./t_sockv4 -C -e -n 20 -l 15 localhost 4000 # client sender
./t_sockv4 -S -e -n 20 -l 15 4000 # server sender
./t_sockv4 -C -r -n 20 -l 15 localhost 4000 # client receiver
```
## Roadmap ## Roadmap
- [X] tsock-v1 - [X] tsock-v1
- [X] tsock-v2 - [X] tsock-v2
- [X] tsock-v3 - [WIP] tsock-v3
- [X] tsock-v4 - [ ] tsock-v4
- [X] server can handle multiple requests simultaneously
- [X] server doesn't stop after the connection ends
- [X] both client and server can assume sender/receiver roles
Every version is fully functional.

220
tsock_compliquev1.c Normal file
View file

@ -0,0 +1,220 @@
/* librairie standard ... */
#include <stdlib.h>
/* pour getopt */
#include <unistd.h>
/* déclaration des types de base */
#include <sys/types.h>
/* constantes relatives aux domaines, types et protocoles */
#include <sys/socket.h>
/* constantes et structures propres au domaine UNIX */
#include <sys/un.h>
/* constantes et structures propres au domaine INTERNET */
#include <netinet/in.h>
/* structures retournées par les fonctions de gestion de la base de
données du réseau */
#include <netdb.h>
/* pour les entrées/sorties */
#include <stdio.h>
/* pour la gestion des erreurs */
#include <errno.h>
#define BASE_SIZE 10
void construire_message(char *message, char motif, int lg, int num_message) {
int i;
printf("\nSOURCE : Envoi n°%d (%d) [",num_message,lg);
char* indice_message = malloc(sizeof(char)* 5);
_itoa(num_message,indice_message,10);
int nb_zeros=1;
while (num_message > 0){
num_message/=10;
nb_zeros++;
}
for (int j=0; j< 5-nb_zeros; j++){
message[j]='-';
}
int l=0;
for (int k=5-nb_zeros;k<5;k++){
message[k]=indice_message[l];
l++;
}
for (i=0;i<lg;i++) message[i] = motif;
strcpy(message,indice_message);
printf("]\n");
}
void afficher_message_source(char *message, int lg, int num_message) {
int i;
printf("\nPUIT : Reception n°%d (%d) [",num_message+1,lg);
for (i=0;i<lg;i++){
printf("%c", message[i]);
}
printf("]\n");
}
int main (int argc, char **argv)
{
int c;
extern char *optarg;
extern int optind;
int nb_message = -1; /* Nb de messages à envoyer ou à recevoir, par défaut : 10 en émission, infini en réception */
int source = -1 ; /* 0=puits, 1=source */
int udp=0; /* 0=TCP, 1=UDP */
while ((c = getopt(argc, argv, "pn:su")) != -1) {
switch (c) {
case 'p':
if (source == 1) {
printf("usage: cmd [-p|-s][-n ##]\n");
exit(1);
}
source = 0;
break;
case 's':
if (source == 0) {
printf("usage: cmd [-p|-s][-n ##]\n");
exit(1) ;
}
source = 1;
break;
case 'n':
nb_message = atoi(optarg);
break;
case 'u':
udp=1;
break;
default:
printf("usage: cmd [-p|-s][-n ##]\n");
break;
}
}
char* nom_machine_distante;
// Recuperation du port
int port=atoi(argv[argc-1]);
port = htons(port);
char* message = malloc(BASE_SIZE * sizeof(char));
if (source == -1) {
printf("usage: cmd [-p|-s][-n ##]\n");
exit(1) ;
}
if (source == 1) {
printf("on est dans le source\n");
//Recuperation du nom logique
nom_machine_distante=argv[argc-2];
}
else
printf("on est dans le puits\n");
if (nb_message != -1) {
if (source == 1)
printf("nb de tampons à envoyer : %d\n", nb_message);
else
printf("nb de tampons à recevoir : %d\n", nb_message);
} else {
if (source == 1) {
nb_message = 10 ;
printf("nb de tampons à envoyer = 10 par défaut\n");
} else
printf("nb de tampons à envoyer = infini\n");
}
if (udp==1){
// Creation du socket local
int sock= socket(AF_INET,SOCK_DGRAM,0);
if (source==1) {
// Creation de l'adresse du socket distant
struct hostent *hp ;
struct sockaddr_in adr_dest;
int longueur_adr_dest = sizeof(adr_dest);
int longueur_message = BASE_SIZE;
memset((char *)& adr_dest, 0, sizeof(adr_dest)) ;
adr_dest.sin_family=AF_INET;
adr_dest.sin_port=port;
if ((hp = gethostbyname(nom_machine_distante)) == NULL) {
printf("erreur gethostbyname\n") ;
exit(1) ;
}
memcpy( (char*)&(adr_dest.sin_addr.s_addr),
hp->h_addr,
hp->h_length ) ;
for (int i = 0; i < nb_message; i++) {
// Construction du message
construire_message(message, 'a' + (i % 26), BASE_SIZE,i);
// Envoi du message
sendto(sock,message,longueur_message,0,(struct sockaddr*)&adr_dest,longueur_adr_dest);
}
exit(0);
}
else {
// Creation de l'adresse du socket distant
struct sockaddr_in adr_locale;
int longueur_adr_locale = sizeof(adr_locale);
int longueur_message = BASE_SIZE;
memset((char *)& adr_locale, 0, sizeof(adr_locale)) ;
adr_locale.sin_family=AF_INET;
adr_locale.sin_port=port;
adr_locale.sin_addr.s_addr = INADDR_ANY;
// Bind the local socket to any local address (ie any available interface)
if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) {
printf("failed to bind\n");
exit(1);
}
int i=0;
while (1) {
// Receive a single message because we are lazy
recvfrom(sock, message, longueur_message, 0, NULL, NULL);
// Afficher notre seule et unique triste message
afficher_message_source(message, longueur_message,i);
i++;
}
exit(0);
}
}
}

View file

@ -72,8 +72,7 @@ int main (int argc, char **argv) {
char* message = malloc(BASE_SIZE * sizeof(char)); char* message = malloc(BASE_SIZE * sizeof(char));
// At least one option -s or -u required. UDP is also required for this version. if (source == -1) {
if (source == -1 || !udp) {
print_usage(argv[0]); print_usage(argv[0]);
exit(1) ; exit(1) ;
} }
@ -96,7 +95,7 @@ int main (int argc, char **argv) {
nb_message = 10 ; nb_message = 10 ;
printf("nb de tampons à envoyer = 10 par défaut\n"); printf("nb de tampons à envoyer = 10 par défaut\n");
} else } else
printf("nb de tampons à recevoir = infini\n"); printf("nb de tampons à envoyer = infini\n");
} }
if (udp==1){ if (udp==1){

View file

@ -92,7 +92,7 @@ int main (int argc, char **argv) {
nb_message = 10 ; nb_message = 10 ;
printf("nb de tampons à envoyer = 10 par défaut\n"); printf("nb de tampons à envoyer = 10 par défaut\n");
} else } else
printf("nb de tampons à recevoir = infini\n"); printf("nb de tampons à envoyer = infini\n");
} }
if (udp==1){ if (udp==1){

View file

@ -26,7 +26,7 @@ void afficher_message_envoi(char *message, int lg, int numero_envoi);
void afficher_message_reception(char *message, int lg, int numero_envoi); void afficher_message_reception(char *message, int lg, int numero_envoi);
// Permet de compter le nombre de digits d'un nombre, utile pour l'affichage [--143 ...] // Permet de compter le nombre de digits d'un nombre, utile pour l'affichage [--143 ...]
// (base 10). Première solution d'affichage mais nous nous servons finalement de snprintf(). // (base 10)
int count_digits(int lg); int count_digits(int lg);
// Affiche l'usage de l'outil // Affiche l'usage de l'outil
@ -132,7 +132,7 @@ int main (int argc, char **argv)
lg,port,nb_message,(udp)?"UDP":"TCP",nom_machine_distante); lg,port,nb_message,(udp)?"UDP":"TCP",nom_machine_distante);
} else { } else {
printf("PUITS:lg_mesg_lu=%d,port=%d,nb_receptions=",lg,port); printf("PUITS:lg_mesg_lu=%d,port=%d,nb_receptions=",lg,port);
if (nb_message==-1 && !source) { if (nb_message!=-1 && !source) {
printf("infini"); printf("infini");
} }
else { else {

View file

@ -1,425 +0,0 @@
/* librairie standard ... */
#include <stdlib.h>
/* pour getopt */
#include <unistd.h>
/* déclaration des types de base */
#include <sys/types.h>
/* constantes relatives aux domaines, types et protocoles */
#include <sys/socket.h>
/* constantes et structures propres au domaine UNIX */
#include <sys/un.h>
/* constantes et structures propres au domaine INTERNET */
#include <netinet/in.h>
/* structures retournées par les fonctions de gestion de la base de
données du réseau */
#include <netdb.h>
/* pour les entrées/sorties */
#include <stdio.h>
/* pour la gestion des erreurs */
#include <errno.h>
#define QUEUE_SIZE 5 // Taille de la file d'attente du listen()
// Remplit le message de lg caractères motif
void construire_message(char* message, char motif, int lg, int numero_envoi);
// Affichage distinct entre envoi et reception pour une facilité d'utilisation
void afficher_message_envoi(char *message, int lg, int numero_envoi);
void afficher_message_reception(char *message, int lg, int numero_envoi);
// Affiche l'usage de l'outil
void print_usage(char* arg0);
int main (int argc, char **argv)
{
int c;
extern char *optarg;
extern int optind;
int nb_message = -1; /* Nb de messages à envoyer ou à recevoir, par défaut : 10 en émission, infini en réception */
int source = -1 ; /* 0=puits, 1=source */
int udp = 0; /* 0=TCP, 1=UDP */
int lg = -1; /* Longueur des messages à envoyer ou recevoir: par défaut 30 octets */
int client = 0; /* 0 not client, 1 client */
int serveur = 0; /* 0 not server, 1 server */
int emetteur = 0; /* 0 not sender, 1 sender */
int recepteur = 0; /* 0 not receiver, 1 receiver */
while ((c = getopt(argc, argv, "pn:sul:CSer")) != -1) {
switch (c) {
case 'p':
if (source == 1) {
print_usage(argv[0]);
exit(1);
}
source = 0;
break;
case 's':
if (source == 0) {
print_usage(argv[0]);
exit(1) ;
}
source = 1;
break;
case 'n':
nb_message = atoi(optarg);
// Packets are numerotated with 5 figures, which means the number of
// packets send can't be bigger than (or equal) 10 ** 6
if(nb_message >= 100000 || nb_message <= 0) {
print_usage(argv[0]);
exit(1);
}
break;
case 'u':
udp=1;
break;
case 'l':
lg=atoi(optarg);
// A TCP packet is roughly 1500 bytes. We allow for some overhead.
// We provide an MTU of 1400 bytes.
// We also to send at least a message of 5 characters length for indice packet
if(lg >= 1400 || lg < 5) {
print_usage(argv[0]);
exit(1);
}
break;
/* -c and -e options stand only for TCP exchange */
case 'C':
client=1;
if (udp || serveur) {
print_usage(argv[0]);
exit(0);
}
break;
case 'S':
serveur = 1;
if (udp || client) {
print_usage(argv[0]);
exit(0);
}
break;
case 'e':
emetteur=1;
if (udp || recepteur) {
print_usage(argv[0]);
exit(0);
}
break;
case 'r':
recepteur=1;
if (udp || emetteur) {
print_usage(argv[0]);
exit(0);
}
break;
default:
print_usage(argv[0]);
break;
}
}
// Little verification of TCP arguments.
// Machine must be a server or a client as once,
// as well as a sender or receiver.
if (!udp) {
if ((!recepteur && !emetteur) || (!serveur && !client)) {
print_usage(argv[0]);
exit(0);
}
}
// Variable qui va stocker le nom logique de la machine avec qui on communique
char* nom_machine_distante;
//Allocation de la variable stockant un message, il est de la taille donnée en paramètre
char* message = malloc(lg * sizeof(char));
// Recuperation du port
int port=atoi(argv[argc-1]);
// Default set of packet length : 30 bytes
if (lg == -1) {
lg=30;
}
// If number of messages is not fixed for the source, it is set to 10 messages
if (nb_message == -1 && (source || !udp)) {
nb_message = 10 ;
}
//Affichage des informations de communication initiée
if (source || emetteur) {
//Recuperation du nom logique
nom_machine_distante=argv[argc-2];
printf("SOURCE:lg_mesg_emis=%d,port=%d,nb_envois=%d,TP=%s",
lg,port,nb_message,(udp)?"UDP":"TCP");
if (client) {
printf(",dest=%s",nom_machine_distante);
}
printf("\n");
} else {
printf("PUITS:lg_mesg-lu=%d,port=%d,nb_receptions=",lg,port);
if (nb_message!=-1 && !source) {
printf("infini");
}
else {
printf("%d",nb_message);
}
printf(", TP=%s\n",(udp)?"UDP":"TCP");
}
/*******************************UDP COMMUNICATION*************************************/
if (udp==1){
// Creation du socket local
int sock= socket(AF_INET,SOCK_DGRAM,0);
if (source==1) {
// Creation de l'adresse du socket distant
struct hostent *hp ;
struct sockaddr_in adr_dest;
int longueur_adr_dest = sizeof(adr_dest);
int longueur_message = lg;
memset((char *)& adr_dest, 0, sizeof(adr_dest)) ;
adr_dest.sin_family=AF_INET;
adr_dest.sin_port=port;
if ((hp = gethostbyname(nom_machine_distante)) == NULL) {
printf("erreur gethostbyname\n") ;
exit(1) ;
}
memcpy( (char*)&(adr_dest.sin_addr.s_addr),
hp->h_addr,
hp->h_length ) ;
for (int i = 0; i < nb_message; i++) {
// Construction du message
construire_message(message, 'a' + (i % 26), lg, i+1);
// Envoi du message
afficher_message_envoi(message,lg,i+1);
sendto(sock,message,longueur_message,0,(struct sockaddr*)&adr_dest,longueur_adr_dest);
}
}
else {
// Creation de l'adresse du socket distant
struct sockaddr_in adr_locale;
int longueur_adr_locale = sizeof(adr_locale);
memset((char *)& adr_locale, 0, sizeof(adr_locale)) ;
adr_locale.sin_family=AF_INET;
adr_locale.sin_port=port;
adr_locale.sin_addr.s_addr = INADDR_ANY;
// Bind the local socket to any local address (ie any available interface)
if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) {
printf("failed to bind\n");
exit(1);
}
// Suivi du numéro de message reçu
int k=0;
while (recvfrom(sock, message, lg, 0, NULL, NULL)) {
k++;
// Afficher notre seule et unique triste message
afficher_message_reception(message, lg, k);
}
}
}
/*******************************TCP COMMUNICATION*************************************/
else{
// Creation du socket local
int sock= socket(AF_INET,SOCK_STREAM,0);
//The server shall establish the connexion
if (client) {
// Creation de l'adresse du socket distant
struct hostent *hp ;
struct sockaddr_in adr_dest;
int longueur_adr_dest = sizeof(adr_dest);
int longueur_message = lg;
memset((char *)& adr_dest, 0, sizeof(adr_dest)) ;
adr_dest.sin_family=AF_INET;
adr_dest.sin_port=port;
if ((hp = gethostbyname(nom_machine_distante)) == NULL) {
printf("erreur gethostbyname\n") ;
exit(1) ;
}
memcpy( (char*)&(adr_dest.sin_addr.s_addr),
hp->h_addr,
hp->h_length ) ;
// Demande de connexion
int succ;
if ((succ=connect(sock,(struct sockaddr*) &adr_dest,longueur_adr_dest))!=0){
printf("Echec connect");
exit(1);
}
// Envoi ou reception des messages
for (int i = 0; i < nb_message; i++) {
if (emetteur){
// Construction du message
construire_message(message, 'a' + (i % 26), lg, i+1);
afficher_message_envoi(message,lg,i+1);
// Envoi du message
write(sock,message,longueur_message);
}
if (recepteur) {
if ((read(sock, message, longueur_message)) < 0){
printf("échec du read\n") ; exit(1) ;}
afficher_message_reception(message, longueur_message,i+1) ;
}
}
// Close socket to avoid dangling connections
close(sock);
}
// The server shall accept the connexion
if (serveur) {
// Creation de l'adresse du socket local
struct sockaddr_in adr_locale;
socklen_t longueur_adr_locale = sizeof(adr_locale);
int longueur_message = lg;
memset((char *)& adr_locale, 0, sizeof(adr_locale)) ;
adr_locale.sin_family=AF_INET;
adr_locale.sin_port=port;
adr_locale.sin_addr.s_addr = INADDR_ANY;
// Bind the local socket to any local address (ie any available interface)
if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) {
printf("failed to bind\n");
exit(1);
}
// Set listening queue size
if (listen(sock, QUEUE_SIZE) == -1) {
printf("échec et mat listen\n");
exit(1);
}
int sock_bis;
while(1) {
// Accept a single connection on the main thread
if ((sock_bis = accept( sock, (struct sockaddr *)&adr_locale, &longueur_adr_locale)) == -1){
printf("échec du accept\n") ;
exit(1) ;
}
// On crée un processus pour chaque connexion TCP acceptée
switch (fork() ) {
case - 1 : /* il y a une erreur */
printf("erreur fork\n") ; exit(1) ;
case 0 : /* on est dans le proc. fils */
close(sock) ; /* fermeture socket du proc. père */
for (int i=0 ; i < nb_message ; i ++) {
// Server sends packets with -e
if (emetteur){
// Construction du message
construire_message(message, 'a' + (i % 26), lg, i+1);
afficher_message_envoi(message,lg,i+1);
// Envoi du message
write(sock_bis,message,longueur_message);
}
// Server receives packets with -r
if (recepteur) {
if ((read(sock_bis, message, longueur_message)) < 0){
printf("échec du read\n") ; exit(1) ;}
afficher_message_reception(message, longueur_message,i+1) ;
}
}
close(sock_bis);
exit(0) ;
default : /* on est dans le proc. père */
close(sock_bis) ; /* fermeture socket du proc. fils
Connexion stay opened for further exchanges */
}
}
}
}
exit(0);
}
void construire_message(char *message, char motif, int lg, int numero_envoi) {
int i;
snprintf(message, lg,"% 5d",numero_envoi);
for (i=5;i<lg;i++) message[i] = motif;
}
void afficher_message_envoi(char *message, int lg, int numero_envoi) {
int i;
printf("SOURCE: Envoi n°%d (%d) [",numero_envoi,lg);
for (i=0;i<lg;i++){
printf("%c", message[i]);
}
printf("]\n");
}
void afficher_message_reception(char *message, int lg, int numero_envoi) {
int i;
printf("PUITS: Reception n°%d (%d) [",numero_envoi,lg);
for (i=0;i<lg;i++){
printf("%c", message[i]);
}
printf("]\n");
}
void print_usage(char* arg0) {
printf("usage: %s [-psuCSer] [-n nb_messages] [-l mess_length] [host] <port>\n", arg0);
printf("parameters: host With -s or -C, address of the host to connect to. Required with -s or -C.\n");
printf(" port Port to connect or bind to. Required.\n");
printf("options: -l mess_length Size of the messages to send. Min 5. Max 1400. Default 30.\n");
printf(" -n nb_messages Number of messages to send. Min 1. Default 10. Ignored with -p.\n");
printf(" -p Runs a TCP/UDP sink. Incompatible with -s.\n");
printf(" -s Runs a TCP/UDP faucet. Incompatible with -p.\n");
printf(" -C Client of a TCP connexion. Incompatible with -S and -u. Requires -e or -r.\n");
printf(" -S Server of a TCP connexion. Incompatible with -C and -u. Requires -e or -r.\n");
printf(" -e Packets issuer of a TCP connexion. Incompatible with -r and -u.\n");
printf(" -r Packets receiver of a TCP connexion. Incompatible with -e and -u.\n");
}

View file

@ -1,372 +0,0 @@
/* librairie standard ... */
#include <stdlib.h>
/* pour getopt */
#include <unistd.h>
/* déclaration des types de base */
#include <sys/types.h>
/* constantes relatives aux domaines, types et protocoles */
#include <sys/socket.h>
/* constantes et structures propres au domaine UNIX */
#include <sys/un.h>
/* constantes et structures propres au domaine INTERNET */
#include <netinet/in.h>
/* structures retournées par les fonctions de gestion de la base de
données du réseau */
#include <netdb.h>
/* pour les entrées/sorties */
#include <stdio.h>
/* pour la gestion des erreurs */
#include <errno.h>
#define QUEUE_SIZE 5
void construire_message(char* message, char motif, int lg, int numero_envoi);
// Affichage distinct entre envoi et reception pour une facilité d'utilisation
void afficher_message_envoi(char *message, int lg, int numero_envoi);
void afficher_message_reception(char *message, int lg, int numero_envoi);
int main (int argc, char **argv)
{
int c;
extern char *optarg;
extern int optind;
int nb_message = -1; /* Nb de messages à envoyer ou à recevoir, par défaut : 10 en émission, infini en réception */
int source = -1 ; /* 0=puits, 1=source */
int udp = 0; /* 0=TCP, 1=UDP */
int lg = -1; /* Longueur des messages à envoyer ou recevoir: par défaut 30 octets */
int client = 0 /* 0 not client, 1 client */
int emetteur = 0 /* 0 not sender, 1 sender */
while ((c = getopt(argc, argv, "pn:sul:ce")) != -1) {
switch (c) {
case 'p':
if (source == 1) {
printf("usage: cmd [-p|-s][-n ##]\n");
exit(1);
}
source = 0;
break;
case 's':
if (source == 0) {
printf("usage: cmd [-p|-s][-n ##]\n");
exit(1) ;
}
source = 1;
break;
case 'n':
nb_message = atoi(optarg);
// Packets are numerotated with 5 figures, which means the number of
// packets send can't be bigger than (or equal) 10 ** 6
if(nb_message >= 100000) {
printf("Too many packets");
exit(1);
}
break;
case 'u':
udp=1;
break;
case 'l':
lg=atoi(optarg);
// A TCP packet is roughly 1500 bytes. We allow for some overhead.
// We provide an MTU of 1400 bytes.
// We also to send at least a message of 5 characters length for indice packet
if(lg >= 1400 || lg < 5) {
printf("Messages too long");
exit(1);
}
break;
/* -c and -e options stand only for TCP exchange */
case 'c':
client=1;
if (udp == 1){
printf("No option -c for UDP");
exit(0);
}
break;
case 'e':
emetteur=1;
if (udp == 1){
printf("No option -e for UDP");
exit(0);
}
break;
default:
printf("usage: cmd [-p|-s][-n ##]\n");
break;
}
}
char* nom_machine_distante;
// Recuperation du port
int port=atoi(argv[argc-1]);
//port = htons(port);
// Default set of packet length : 30 bytes
if (lg == -1) {
lg=30;
}
//Allocation du message, il est de la taille donnée en paramètre
char* message = malloc(lg * sizeof(char));
if (source == -1) {
printf("usage: cmd [-p|-s][-n ##]\n");
exit(1) ;
}
// If number of messages is not fixed for the source, it is set to 10 messages
if (nb_message == -1 && source ) {
nb_message = 10 ;
}
//Affichage des informations de communication initiée
if (source == 1) {
//Recuperation du nom logique
nom_machine_distante=argv[argc-2];
printf("SOURCE:lg_mesg_emis=%d,port=%d,nb_envois=%d,TP=%s,dest=%s\n",
lg,port,nb_message,(udp)?"UDP":"TCP",nom_machine_distante);
} else {
printf("PUITS:lg_mesg-lu=%d,port=%d,nb_receptions=",lg,port);
if (nb_message!=-1 && !source) {
printf("infini");
}
else {
printf("%d",nb_message);
}
printf(", TP=%s\n",(udp)?"UDP":"TCP");
}
/*******************************UDP COMMUNICATION*************************************/
if (udp==1){
// Creation du socket local
int sock= socket(AF_INET,SOCK_DGRAM,0);
if (source==1) {
// Creation de l'adresse du socket distant
struct hostent *hp ;
struct sockaddr_in adr_dest;
int longueur_adr_dest = sizeof(adr_dest);
int longueur_message = lg;
memset((char *)& adr_dest, 0, sizeof(adr_dest)) ;
adr_dest.sin_family=AF_INET;
adr_dest.sin_port=port;
if ((hp = gethostbyname(nom_machine_distante)) == NULL) {
printf("erreur gethostbyname\n") ;
exit(1) ;
}
memcpy( (char*)&(adr_dest.sin_addr.s_addr),
hp->h_addr,
hp->h_length ) ;
for (int i = 0; i < nb_message; i++) {
// Construction du message
construire_message(message, 'a' + (i % 26), lg, i+1);
// Envoi du message
afficher_message_envoi(message,lg,i+1);
sendto(sock,message,longueur_message,0,(struct sockaddr*)&adr_dest,longueur_adr_dest);
}
}
else {
// Creation de l'adresse du socket distant
struct sockaddr_in adr_locale;
int longueur_adr_locale = sizeof(adr_locale);
memset((char *)& adr_locale, 0, sizeof(adr_locale)) ;
adr_locale.sin_family=AF_INET;
adr_locale.sin_port=port;
adr_locale.sin_addr.s_addr = INADDR_ANY;
// Bind the local socket to any local address (ie any available interface)
if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) {
printf("failed to bind\n");
exit(1);
}
// Suivi du numéro de message reçu
int k=0;
while (recvfrom(sock, message, lg, 0, NULL, NULL)) {
k++;
// Afficher notre seule et unique triste message
afficher_message_reception(message, lg, k);
}
}
}
/*******************************TCP COMMUNICATION*************************************/
else{
// Creation du socket local
int sock= socket(AF_INET,SOCK_STREAM,0);
//The server shall establish the connexion
if (source==1) {
// Creation de l'adresse du socket distant
struct hostent *hp ;
struct sockaddr_in adr_dest;
int longueur_adr_dest = sizeof(adr_dest);
int longueur_message = lg;
memset((char *)& adr_dest, 0, sizeof(adr_dest)) ;
adr_dest.sin_family=AF_INET;
adr_dest.sin_port=port;
if ((hp = gethostbyname(nom_machine_distante)) == NULL) {
printf("erreur gethostbyname\n") ;
exit(1) ;
}
memcpy( (char*)&(adr_dest.sin_addr.s_addr),
hp->h_addr,
hp->h_length ) ;
// Demande de connexion
int succ;
if ((succ=connect(sock,(struct sockaddr*) &adr_dest,longueur_adr_dest))!=0){
printf("Echec connect");
exit(1);
}
// Envoi des messages
for (int i = 0; i < nb_message; i++) {
// Construction du message
construire_message(message, 'a' + (i % 26), lg, i+1);
afficher_message_envoi(message,lg,i+1);
// Envoi du message
write(sock,message,longueur_message);
}
// Close socket to avoid dangling connections
close(sock);
}
else {
// Creation de l'adresse du socket local
struct sockaddr_in adr_locale;
socklen_t longueur_adr_locale = sizeof(adr_locale);
int longueur_message = lg;
memset((char *)& adr_locale, 0, sizeof(adr_locale)) ;
adr_locale.sin_family=AF_INET;
adr_locale.sin_port=port;
adr_locale.sin_addr.s_addr = INADDR_ANY;
// Bind the local socket to any local address (ie any available interface)
if (bind(sock, (struct sockaddr *) &adr_locale, longueur_adr_locale) == -1) {
printf("failed to bind\n");
exit(1);
}
// set listening queue size
if (listen(sock, QUEUE_SIZE) == -1) {
printf("échec et mat listen\n");
exit(1);
}
int sock_bis;
while(1) {
// Accept a single connection on the main thread
if ((sock_bis = accept( sock, (struct sockaddr *)&adr_locale, &longueur_adr_locale)) == -1){
printf("échec du accept\n") ;
exit(1) ;
}
printf("socket accepte:%d\n",sock_bis);
switch (fork() ) {
case - 1 : /* il y a une erreur */
printf("erreur fork\n") ; exit(1) ;
case 0 : /* on est dans le proc. fils */
close(sock) ; /* fermeture socket du proc. père */
for (int i=0 ; i < nb_message ; i ++) {
if ((read(sock_bis, message, longueur_message)) < 0){
printf("échec du read\n") ; exit(1) ;}
afficher_message_reception(message, longueur_message,i+1) ;
}
close(sock_bis);
exit(0) ;
default : /* on est dans le proc. père */
close(sock_bis) ; /* fermeture socket du proc. fils
Connexion stay opened for further exchanges */
}
}
}
}
exit(0);
}
void construire_message(char *message, char motif, int lg, int numero_envoi) {
int i;
snprintf(message, lg,"% 5d",numero_envoi);
for (i=5;i<lg;i++) message[i] = motif;
}
void afficher_message_envoi(char *message, int lg, int numero_envoi) {
int i;
printf("SOURCE: Envoi n°%d (%d) [",numero_envoi,lg);
for (i=0;i<lg;i++){
printf("%c", message[i]);
}
printf("]\n");
}
void afficher_message_reception(char *message, int lg, int numero_envoi) {
int i;
printf("PUITS: Reception n°%d (%d) [",numero_envoi,lg);
for (i=0;i<lg;i++){
printf("%c", message[i]);
}
printf("]\n");
}