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 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
| // Nom: Serveur TCP/IP
#include <stdio.h> // perror()
#include <netinet/in.h> // sockaddr_in et INADDR_ANY
#include <sys/socket.h> // socket(), bind(), recv(), send()
#include <sys/types.h> // socket(), bind(), recv(), send(), wait()
#include <string.h> // memset()
#include <signal.h> // signal()
#include <wait.h> // wait()
#include <pthread.h> // pour les thread
#include <stdlib.h> // pour malloc()
// Pour open()
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// Definition des constantes symboliques
#define TAILLE_FILE_DATTENTE_CONNEXION 5 // Taille de la file d'attente de demandes de connexion
#define NUMERO_PORT_SERVEUR 30000
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // Création du mutex
pthread_cond_t condition = PTHREAD_COND_INITIALIZER; // Création de la condition
// routine d'interception du signal SIGCHLD emis par les fils
void intercepterSignalSIGCHLD(int numeroSignalRecu);
// prototypes des fonctions
//int BougerRobot(int *socketConnectee);
static void *BougerRobot(void *socket);
static void *visualiser(void * argument);
int main()
{
// couple adresse IP, numero de port serveur
struct sockaddr_in coupleAdresseIPNumeroPortServeur;
// couple adresse IP, numero de port client
struct sockaddr_in coupleAdresseIPNumeroPortClient;
int socketDemandeDeConnexion; // socket permettant d'effectuer une demande de connexion
int socketConnectee; // socket dediee a une connexion etablie
socklen_t longueurClient; // longueur du couple adresse IP, numero de port du client
int optval;
// Mise en place de l'interception de SIGCHLD emis par les fils
signal(SIGCHLD,intercepterSignalSIGCHLD);
// Initialiser les structures a des octets de valeurs
memset(&coupleAdresseIPNumeroPortServeur,0,sizeof(struct sockaddr_in));
memset(&coupleAdresseIPNumeroPortClient,0,sizeof(struct sockaddr_in));
// Creer la socket serveur en mode TCP
if ((socketDemandeDeConnexion = socket(PF_INET,SOCK_STREAM,0)) < 0)
{
perror("socket");
return -1;
}
// Reutiliser le meme port en cas d'interruption brutal du serveur
optval = 1;
setsockopt(socketDemandeDeConnexion, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
// Associer la socket serveur a un couple adresse IP, numero de port socket du domaine reseau
coupleAdresseIPNumeroPortServeur.sin_family = AF_INET;
// INADDR_ANY pour accepter les requetes de toutes les interfaces reseau du serveur
coupleAdresseIPNumeroPortServeur.sin_addr.s_addr = htonl(INADDR_ANY);
// affecter le numero de pott de l'application
coupleAdresseIPNumeroPortServeur.sin_port = htons(NUMERO_PORT_SERVEUR);
if (bind(socketDemandeDeConnexion,(struct sockaddr *)(&coupleAdresseIPNumeroPortServeur),sizeof(struct sockaddr_in)) < 0)
{
perror("bind");
return -1;
}
// Creer une file d'attente de demandes de connexion
if (listen(socketDemandeDeConnexion,TAILLE_FILE_DATTENTE_CONNEXION) <0)
{
perror("listen");
return -1;
}
longueurClient = sizeof(struct sockaddr_in);
// Création des variables de thread
pthread_t idThreadBougerRobot; // Identifiant du thread bouger
pthread_t idThreadVisualisation; // Identifiant du thread visualiser
// Variables identification du client
char idThread[2];
int idT;
while(1)
{
// Attendre une demande de connexion du client
socketConnectee = accept(socketDemandeDeConnexion,(struct sockaddr *)(&coupleAdresseIPNumeroPortClient),&longueurClient);
if (socketConnectee < 0)
{
perror ("accept");
}
else
{
idT = recv(socketConnectee, idThread, sizeof(idThread), 0);
printf("Client: %d\n", idT);
if(idT == 1)
{
// Créer le premier thread
if (pthread_create (&idThreadBougerRobot, NULL, BougerRobot, (void *) &socketConnectee) != 0)
{
perror("pthread_create() bouger:");
return -1;
}
// pthread_join(idThreadBougerRobot, NULL);
printf("Thread bouger robot, créé.\n");
}
if (idT == 2)
{
// Créer le second thread
if (pthread_create (&idThreadVisualisation, NULL, visualiser, NULL) != 0)
{
perror("pthread_create() afficher:");
return -1;
}
printf("Thread visualisation unity, créé.\n");
}
// dans le pere fermer dans le pere la socket connectee
if(close(socketConnectee) < 0)
{
perror("close");
return -1;
}
}
}
return 0;
}
void intercepterSignalSIGCHLD(int numeroSignalRecu)
{
wait(NULL);
}
static void *BougerRobot(void *socket)
{
char lettre;
char *lettreReponse;
int pvsocket = *(int *) socket;
printf("%d\n", pvsocket);
// Recevoir la requête
if (recv(pvsocket, &lettre, sizeof(lettre), 0) == -1)
{
perror("recvfrom");
}
// Traiter la requete
*lettreReponse = lettre + 1;
printf("%c\n", *lettreReponse);
// Envoyer la réponse
if (send(pvsocket, &lettreReponse, sizeof(lettreReponse), 0) == -1)
{
perror("sendto");
}
}
static void *visualiser(void * argument)
{
int compteur = 0, nombre = 0;
srand(time(NULL));
while(1) /* Boucle infinie */
{
nombre = rand()%10; /* On tire un nombre entre 0 et 10 */
compteur += nombre; /* On ajoute ce nombre à la variable compteur */
printf("\n%d", compteur);
if(compteur >= 20) /* Si compteur est plus grand ou égal à 20 */
{
pthread_mutex_lock (&mutex); /* On verrouille le mutex */
pthread_cond_signal (&condition); /* On délivre le signal : condition remplie */
pthread_mutex_unlock (&mutex); /* On déverrouille le mutex */
compteur = 0; /* On remet la variable compteur à 0 */
}
sleep (1); /* On laisse 1 seconde de repos */
}
pthread_exit(NULL); /* Fin du thread */
} |
Partager