+#include "ServeurCompo.h"
+
+#include "../Contraintes/CPointIsole.h"
+#include "../Contraintes/CPointAppart1D.h"
+#include "../Contraintes/CPointAppart1C.h"
+#include "../Contraintes/CPointInter2D.h"
+#include "../Contraintes/CPointMilieu2P.h"
+#include "../Contraintes/CPointInter2C.h"
+#include "../Contraintes/CPointInter1C1D.h"
+#include "../Contraintes/CPointCentre1C.h"
+
+#include "../Contraintes/CDtePassant2P.h"
+#include "../Contraintes/CDteHorizPassant1P.h"
+#include "../Contraintes/CDteVertPassant1P.h"
+#include "../Contraintes/CDtePerp1DPassant1P.h"
+#include "../Contraintes/CDteParall1D.h"
+#include "../Contraintes/CDteParall1DPassant1P.h"
+#include "../Contraintes/CDteMediatrice2P.h"
+
+#include "../Contraintes/CCerclePassant3P.h"
+#include "../Contraintes/CCerclePassant1P.h"
+#include "../Contraintes/CCercleTangent2D.h"
+
+#include "../Global.h"
+
+#include "unistd.h"
+#include "stdio.h"
+#include "pthread.h"
+#include "string"
+using namespace std;
+
+struct paramthread
+{
+ Socket *sock;
+ ListePoints *points;
+ ListeDroites *droites;
+ ListeCercles *cercles;
+};
+
+void serveurcompo(char *nom, int typeserveur, Connexion * c)
+{
+ switch (c->GetType())
+ {
+ case C_FORK :
+ switch(fork())
+ {
+ case -1 :
+ fprintf(stderr, "Erreur de lancement du fork du serveur %s\n",nom);
+ break;
+
+ case 0 :
+ fk_creercompo(c);
+ break;
+
+ default:
+ delete []nom;
+ delete c;
+ }
+ break;
+
+ case C_THREAD :
+ pthread_t thr;
+ if (pthread_create(&thr,NULL,th_creercompo,(void *)c) != 0)
+ fprintf(stderr,"pthread_create (serveur %s)\n",nom);
+ delete []nom;
+ break;
+ }
+}
+
+void * th_creercompo(void * param)
+{
+ Connexion *p = (Connexion *)param;
+ fk_creercompo(p);
+
+ pthread_exit(NULL);
+}
+
+void fk_creercompo(Connexion * c)
+{
+ Socket * sock;
+ //pthread_t *thr;
+ pthread_t thr;
+
+ //Liste des points, des droites et des cercles définis par contraintes
+ ListePoints points;
+ ListeDroites droites;
+ ListeCercles cercles;
+
+ struct paramthread *param;
+
+ //écoute sur la socket
+ while(1)
+ {
+ if ((sock = c->AttendConnexion()) != NULL)
+ {
+ param = new (struct paramthread);
+ param->sock = sock;
+ param->points = &points;
+ param->droites = &droites;
+ param->cercles = &cercles;
+
+ /*thr = new pthread_t;
+ if (pthread_create(thr,NULL,thread_travail_client,(void *)param) != 0)
+ perror("pthread_create (thread_travail_client)");*/
+ if (pthread_create(&thr,NULL,thread_travail_client,(void *)param) != 0)
+ perror("pthread_create (thread_travail_client)");
+ pthread_detach(thr);
+ }
+ }
+ //quand c'est fini on détruit la connexion
+ delete c;
+}
+
+void *thread_travail_client(void *param)
+{
+ Socket *sock = ((struct paramthread *)param)->sock;
+ ListePoints *points = ((struct paramthread *)param)->points;
+ ListeDroites *droites = ((struct paramthread *)param)->droites;
+ ListeCercles *cercles = ((struct paramthread *)param)->cercles;
+
+ int i, p;
+ //char buffer[TAILLE_BUFFER];
+ char *lecture;
+
+ while (1)
+ {
+ //écoute de la réponse...
+ if ((lecture = sock->Lire()) == NULL)
+ break;
+ #ifdef VERBOSE
+ printf("client : \033[93m\033[40m%s\033[0m\n",lecture);
+ #endif
+ traiterRequete(lecture, sock, *points, *droites, *cercles);
+
+ delete []lecture;
+ }
+
+ #ifdef VERBOSE
+ printf("fin de la thread du client\n");
+ #endif
+ //on détruit la socket du client
+ delete sock;
+ pthread_exit((void *)0);
+
+}
+
+int traiterRequete(const char *ligne, Socket *sock, ListePoints &points, ListeDroites &droites, ListeCercles &cercles)
+{
+ char commande[TAILLE_BUFFER];
+ char *buffer;
+ int position;
+ double r, x, y;
+ int p1,p2,p3;
+ int d1, d2;
+ int c1, c2;
+ int nb;
+ CPoint *pp, *pp1, *pp2, *pp3;
+ CDroite *dd, *dd1, *dd2;
+ CCercle *cc, *cc1, *cc2;
+
+ //lit le type de requête
+ if (sscanf(ligne, "%s %n", commande, &position) !=1)
+ {
+ //aucune commande n'a été tapée
+ return -1;
+ }
+
+ //POINT
+ if (string(commande) == "P")
+ {
+ int position2, type;
+ //lit le type de requête
+ if (sscanf(&(ligne[position]), "%d %n", &type, &position2) !=1)
+ {
+ //il y a une erreur de saisie
+ return -1;
+ }
+ CPoint *p;
+ position2 += position;
+
+ switch(type)
+ {
+ case 1:
+ if (sscanf(&(ligne[position2]),"%lf %lf",&x,&y) != 2)
+ p = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("point isolé : x=%lf, y=%lf\n",x,y);
+ #endif
+ //on va ajouter un nouveau CPointIsole dans les points
+ p = new CPointIsole(x,y);
+ }
+ break;
+
+ case 2:
+ if (sscanf(&(ligne[position2]),"%d %lf %lf",&d1, &x, &y) != 3)
+ p = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("point appartenant à une droite : %lf %lf projeté sur d%d \n",x,y,d1);
+ #endif
+ //on récupère la droite
+ if ((dd = droites.GetDroite(d1)) == NULL)
+ p = NULL;
+ else
+ p = new CPointAppart1D(dd,x,y);
+ }
+ break;
+
+ case 3:
+ if (sscanf(&(ligne[position2]),"%d %lf %lf",&c1,&x,&y) != 3)
+ p = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("point appartenant à un cercle : c%d\n", c1);
+ #endif
+ //on récupère la droite
+ if ((cc = cercles.GetCercle(c1)) == NULL)
+ p = NULL;
+ else
+ p = new CPointAppart1C(cc,x,y);
+ }
+ break;
+
+ case 4:
+ if (sscanf(&(ligne[position2]),"%d %d", &d1, &d2) != 2)
+ p = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("point d'intersection de deux droites : d%d et d%d\n", d1, d2);
+ #endif
+ //on récupère les deux droites
+ if (((dd1 = droites.GetDroite(d1)) == NULL) || ((dd2 = droites.GetDroite(d2)) == NULL))
+ p = NULL;
+ else
+ p = new CPointInter2D(dd1,dd2);
+ }
+ break;
+
+ case 5:
+ if (sscanf(&(ligne[position2]),"%d %d", &c1, &c2) != 2)
+ p = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("point d'intersection entre deux cercles : c%d et c%d\n", c1, c2);
+ #endif
+ //on récupère les deux cercles
+ if (((cc1 = cercles.GetCercle(c1)) == NULL) || ((cc2 = cercles.GetCercle(c2)) == NULL))
+ p = NULL;
+ else
+ p = new CPointInter2C(cc1,cc2);
+ }
+ break;
+
+ case 6:
+ if (sscanf(&(ligne[position2]),"%d %d", &d1, &c1) != 2)
+ p = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("point d'intersection entre une droite et un cercle : d%d et c%d\n", d1, c1);
+ #endif
+ //on récupère le cercle et la droite
+ if (((dd = droites.GetDroite(d1)) == NULL) || ((cc = cercles.GetCercle(c1)) == NULL))
+ p = NULL;
+ else
+ p = new CPointInter1C1D(cc,dd);
+ }
+ break;
+
+ case 7:
+ if (sscanf(&(ligne[position2]),"%d %d", &p1, &p2) != 2)
+ p = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("point milieu de deux points : p%d et p%d\n", p1, p2);
+ #endif
+ //on récupère les deux points
+ if (((pp1 = points.GetPoint(p1)) == NULL) || ((pp2 = points.GetPoint(p2)) == NULL))
+ p = NULL;
+ else
+ p = new CPointMilieu2P(pp1,pp2);
+ }
+ break;
+
+ case 8:
+ if (sscanf(&(ligne[position2]),"%d", &c1) != 1)
+ p = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("point centre d'un cercle : c%d\n", c1);
+ #endif
+ //on récupère le cercle
+ if ((cc = cercles.GetCercle(c1)) == NULL)
+ p = NULL;
+ else
+ p = new CPointCentre1C(cc);
+ }
+ break;
+
+ default:
+ p = NULL;
+ }
+
+ if (p != NULL)
+ {
+ //RECUPERER LE NUMERO ET L'ENVOYER AU CLIENT A LA FIN.
+ int n = points.AjouterPoint(p);
+ //on envoie les solutions possibles
+ p->EnvoyerSolutions(sock);
+ //on lit la solution voulue
+ if (((buffer = sock->Lire()) == NULL) || (sscanf(buffer,"%d",&nb) != 1))
+ nb = 0;
+ else
+ {
+ delete [] buffer;
+ //on envoie le numéro du point créé. Ca tient lieu d'accusé de réception
+ char *buffer2 = new char[TAILLE_BUFFER];
+ sprintf(buffer2,"%d\n",n);
+ sock->Ecrire(buffer2);
+ delete [] buffer2;
+ }
+
+ //On affecte le choix du client
+ p->Choisir(nb);
+ }
+ #ifdef VERBOSE
+ else
+ printf("\033[05m\033[41m\033[97merreurs de paramètres\033[0m\n");
+ #endif
+ }
+
+ //DROITES
+ else
+ if (string(commande) == "D")
+ {
+ int position2, type;
+ //lit le type de requête
+ if (sscanf(&(ligne[position]), "%d %n", &type, &position2) !=1)
+ {
+ //il y a une erreur de saisie
+ return -1;
+ }
+ CDroite *d;
+ position2 += position;
+
+ switch(type)
+ {
+ case 1:
+ if (sscanf(&(ligne[position2]),"%d %d", &p1, &p2) != 2)
+ d = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("droite passant par deux points : p%d et p%d\n", p1, p2);
+ #endif
+ //on récupère les deux points
+ if (((pp1 = points.GetPoint(p1)) == NULL) || ((pp2 = points.GetPoint(p2)) == NULL))
+ d = NULL;
+ else
+ d = new CDtePassant2P(pp1,pp2);
+ }
+ break;
+
+ case 2:
+ if (sscanf(&(ligne[position2]),"%d", &p1) != 1)
+ d = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("droite horizontale passant par un point : p%d\n", p1);
+ #endif
+ //on récupère le point
+ if ((pp = points.GetPoint(p1)) == NULL)
+ d = NULL;
+ else
+ d = new CDteHorizPassant1P(pp);
+ }
+ break;
+
+ case 3:
+ if (sscanf(&(ligne[position2]),"%d", &p1) != 1)
+ d = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("droite verticale passant par un point : p%d\n", p1);
+ #endif
+ //on récupère le point
+ if ((pp = points.GetPoint(p1)) == NULL)
+ d = NULL;
+ else
+ d = new CDteVertPassant1P(pp);
+ }
+ break;
+
+ case 4:
+ if (sscanf(&(ligne[position2]),"%d %d", &d1, &p1) != 2)
+ d = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("droite perpendiculaire à une autre droite passant par un point : d%d et p%d\n", d1, p1);
+ #endif
+ //on récupère le point et la droite
+ if (((pp = points.GetPoint(p1)) == NULL) || ((dd = droites.GetDroite(d1)) == NULL))
+ d = NULL;
+ else
+ d = new CDtePerp1DPassant1P(dd,pp);
+ }
+ break;
+
+ case 5:
+ if (sscanf(&(ligne[position2]),"%d %lf", &d1, &x) != 2)
+ d = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("droite parallèle à une autre droite à une distance d : d%d à %lf\n", d1, x);
+ #endif
+ //on récupère la droite
+ if ((dd = droites.GetDroite(d1)) == NULL)
+ d = NULL;
+ else
+ d = new CDteParall1D(dd,x);
+ }
+ break;
+
+ case 6:
+ if (sscanf(&(ligne[position2]),"%d %d", &d1, &p1) != 2)
+ d = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("droite parallèle à une autre droite passant par un point : d%d et p%d\n", d1, p1);
+ #endif
+ //on récupère la droite et le point
+ if (((dd = droites.GetDroite(d1)) == NULL) || ((pp = points.GetPoint(p1)) == NULL))
+ d = NULL;
+ else
+ d = new CDteParall1DPassant1P(dd,pp);
+ }
+ break;
+
+ case 7:
+ if (sscanf(&(ligne[position2]),"%d %d", &p1, &p2) != 2)
+ d = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("droite médiatrice d'un segment : p%d et p%d\n", p1, p2);
+ #endif
+ //on récupère les points
+ if (((pp1 = points.GetPoint(p1)) == NULL) || ((pp2 = points.GetPoint(p2)) == NULL))
+ d = NULL;
+ else
+ d = new CDteMediatrice2P(pp1,pp2);
+ }
+ break;
+
+ default:
+ d = NULL;
+ }
+
+ if (d != NULL)
+ {
+ int n = droites.AjouterDroite(d);
+ //on envoie les solutions possibles
+ d->EnvoyerSolutions(sock);
+ //on lit la solution voulue
+ if (((buffer = sock->Lire()) == NULL) || (sscanf(buffer,"%d",&nb) != 1))
+ nb = 0;
+ else
+ {
+ delete [] buffer;
+ //on envoie le numéro de la droite créée. Ca tient lieu d'accusé de réception
+ char *buffer2 = new char[TAILLE_BUFFER];
+ sprintf(buffer2,"%d\n",n);
+ sock->Ecrire(buffer2);
+ delete [] buffer2;
+ }
+ //On affecte le choix du client
+ d->Choisir(nb);
+ }
+ #ifdef VERBOSE
+ else
+ printf("\033[05m\033[41m\033[97merreurs de paramètres\033[0m\n");
+ #endif
+ }
+
+ //CERCLES
+ else
+ if (string(commande) == "C")
+ {
+ int position2, type;
+ //lit le type de requête
+ if (sscanf(&(ligne[position]), "%d %n", &type, &position2) !=1)
+ {
+ //il y a une erreur de saisie
+ return -1;
+ }
+ CCercle *c;
+ position2 += position;
+
+ switch(type)
+ {
+ case 1:
+ if (sscanf(&(ligne[position2]),"%d %d %d", &p1, &p2, &p3) != 3)
+ c = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("cercle passant par trois points : p%d, p%d et p%d\n", p1, p2, p3);
+ #endif
+ //on récupère les trois points
+ if (((pp1 = points.GetPoint(p1)) == NULL) || (pp2 = points.GetPoint(p2)) == NULL || (pp3 = points.GetPoint(p3)) == NULL)
+ c = NULL;
+ else
+ c = new CCerclePassant3P(pp1,pp2,pp3);
+ }
+ break;
+
+ case 2:
+ if (sscanf(&(ligne[position2]),"%d %lf %lf %lf", &p1, &r, &x, &y) != 4)
+ c = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("cercle passant par un point et de rayon donné : p%d à %lf près de %lf %lf\n", p1, r, x, y);
+ #endif
+ //on récupère les trois points
+ if ((pp = points.GetPoint(p1)) == NULL)
+ c = NULL;
+ else
+ c = new CCerclePassant1P(pp,r,x,y);
+ }
+ break;
+
+ case 3:
+ if (sscanf(&(ligne[position2]),"%d %lf %lf %lf", &p1, &r, &x, &y) != 4)
+ c = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("cercle passant par un point et de diamètre donné : p%d à %lf près de %lf %lf\n", p1, r, x, y);
+ #endif
+ //on récupère les trois points
+ if ((pp = points.GetPoint(p1)) == NULL)
+ c = NULL;
+ else
+ c = new CCerclePassant1P(pp,r/2.0,x,y);
+ }
+ break;
+
+ case 4:
+ if (sscanf(&(ligne[position2]),"%d %d %lf", &d1, &d2, &r) != 3)
+ c = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("cercle tangent à deux droites et de rayon donné : d%d et d%d à %lf\n", d1, d2, r);
+ #endif
+ //on récupère ledeux droites
+ if (((dd1 = droites.GetDroite(d1)) == NULL) || ((dd2 = droites.GetDroite(d2)) == NULL))
+ c = NULL;
+ else
+ c = new CCercleTangent2D(dd1,dd2,r);
+ }
+ break;
+
+ case 5:
+ if (sscanf(&(ligne[position2]),"%d %d %lf", &c1, &c2, &r) != 3)
+ c = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("cercle tangent à deux cercles et de rayon donné : c%d et c%d à %lf\n", c1, c2, r);
+ #endif
+ c = NULL;
+ }
+ break;
+
+ case 6:
+ if (sscanf(&(ligne[position2]),"%d %d", &p1, &d1) != 2)
+ c = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("cercle passant par un point et tangent à une droite : p%d et d%d\n", p1, d1);
+ #endif
+ c = NULL;
+ }
+ break;
+
+ case 7:
+ if (sscanf(&(ligne[position2]),"%d %d", &p1, &c1) != 2)
+ c = NULL;
+ else
+ {
+ #ifdef VERBOSE
+ printf("cercle passant par un point et tangent à un cercle : p%d et c%d\n", p1, c1);
+ #endif
+ c = NULL;
+ }
+ break;
+
+ default:
+ c = NULL;
+ }
+ if (c != NULL)
+ {
+ int n = cercles.AjouterCercle(c);
+
+ //on envoie les solutions possibles
+ c->EnvoyerSolutions(sock);
+
+ //on lit la solution voulue
+ if (((buffer = sock->Lire()) == NULL) || (sscanf(buffer,"%d",&nb) != 1))
+ nb = 0;
+ else
+ {
+ delete [] buffer;
+ //on envoie le numéro du cercle créé. Ca tient lieu d'accusé de réception
+ char *buffer2 = new char[TAILLE_BUFFER];
+ sprintf(buffer2,"%d\n",n);
+ sock->Ecrire(buffer2);
+ delete [] buffer2;
+ }
+ //On affecte le choix du client
+ c->Choisir(nb);
+ }
+ #ifdef VERBOSE
+ else
+ printf("\033[05m\033[41m\033[97merreurs de paramètres\033[0m\n");
+ #endif
+ }
+
+ //MODIFICATION D'UN POINT
+ else
+ if (string(commande) == "M")
+ {
+ int position2, type;
+ //lit le type de requête
+ if (sscanf(&(ligne[position]), "%d %lf %lf", &p1, &x, &y) == 3)
+ {
+ #ifdef VERBOSE
+ printf("modification d'un point : point p%d vers %lf et %lf\n", p1, x, y);
+ #endif
+ //on récupère le point
+ if (points.GetPoint(p1) != NULL)
+ {
+ points.GetPoint(p1)->ModifierPoint(x,y);
+ //on envoie les coordonnées du point : cela permet au client de
+ //ssavoir si le point a été modifié
+ char *buffer2 = new char[TAILLE_BUFFER];
+ sprintf(buffer2,"%lf %lf\n", (points.GetPoint(p1)->Solution())->GetX(), (points.GetPoint(p1)->Solution())->GetY());
+ sock->Ecrire(buffer2);
+ delete [] buffer2;
+ }
+ #ifdef VERBOSE
+ else
+ printf("\033[05m\033[41m\033[97mle point %d n'existe pas\033[0m\n",p1);
+ #endif
+ }
+ #ifdef VERBOSE
+ else
+ printf("\033[05m\033[41m\033[97merreurs de paramètres\033[0m\n");
+ #endif
+ }
+ //ENVOI DE LISTES
+ else
+ if (string(commande) == "POINTS")
+ {
+ #ifdef VERBOSE
+ printf("Envoi de la liste des points\n");
+ #endif
+ points.EnvoyerListe(sock);
+ }
+ else
+ if (string(commande) == "DROITES")
+ {
+ #ifdef VERBOSE
+ printf("Envoi de la liste des droites\n");
+ #endif
+ droites.EnvoyerListe(sock);
+ }
+ else
+ if (string(commande) == "CERCLES")
+ {
+ #ifdef VERBOSE
+ printf("Envoi de la liste des cercles\n");
+ #endif
+ cercles.EnvoyerListe(sock);
+ }
+ else
+ if (string(commande) == "ALL")
+ {
+ #ifdef VERBOSE
+ printf("Envoi de la liste des points\n");
+ #endif
+ points.EnvoyerListe(sock);
+ #ifdef VERBOSE
+ printf("Envoi de la liste des droites\n");
+ #endif
+ droites.EnvoyerListe(sock);
+ #ifdef VERBOSE
+ printf("Envoi de la liste des cercles\n");
+ #endif
+ cercles.EnvoyerListe(sock);
+ }
+
+ #ifdef VERBOSE
+ //COMMANDE NON RECONNUE
+ else
+ {
+ printf("commande inconnue\n");
+ }
+ #endif
+ return 1;
+}