Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <math.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <pthread.h>
- #define NB_COMPTE 100
- #define GROUP "224.17.11.11"
- #define PORT 55501
- void init(void);
- int consulter (int compte);
- int ajouter (int compte, int valeur);
- int retirer (int compte, int valeur);
- void* receptionMAJ(void* data);
- void envoiMAJ(char * info);
- int solde[NB_COMPTE];
- int main ( int argc, char *argv[]){
- int numero_compte;
- int choix_action;
- int result;
- int valeur;
- int ok;
- int code;
- int desc,desc2,taille;
- int longueur=sizeof(struct sockaddr_in);
- char chaine[1024];
- char maj[1024];
- struct sockaddr_in adr1,adr2;
- /*test nombre de parametres*/
- if (argc != 2){
- perror("Erreur: nombre de parametres incorrect\n\t=>(argv[1]=port) ");
- return -1;
- }
- init();
- /* initialisation et début connection tcp */
- if((desc=socket(AF_INET,SOCK_STREAM,0)) == -1)
- {
- perror("socket ...");exit(1);
- }
- adr1.sin_family=AF_INET;
- adr1.sin_addr.s_addr=htonl(INADDR_ANY);
- adr1.sin_port=htons(atoi(argv[1]));
- if(bind(desc,(struct sockaddr *)&adr1,longueur)==-1)
- {
- perror("bind ...");exit(1);
- }
- if(listen(desc,10)==-1)
- {
- perror("listen ...");exit(1);
- }
- /* fin de l'iniitalisation tcp */
- /*lancement du thread découte udp */
- pthread_t thread0;// On crée un thread
- pthread_create(&thread0, NULL, receptionMAJ, NULL);
- while(1){
- if((desc2=accept(desc,(struct sockaddr *)&adr2,&longueur))==-1)
- {
- perror("bind ...");exit(1);
- }
- ok=1;
- taille=read(desc2,chaine,1024); //reception numero compte
- numero_compte=atoi(chaine);
- printf("Operation sur le compte Numero: %d\n",numero_compte);
- if(numero_compte >NB_COMPTE){
- ok=0;
- code=-2;
- }
- if((consulter(numero_compte)==-1)&&(ok==1)){
- code=-1;
- }
- code =0;
- sprintf(chaine,"%d",code);
- write(desc2,chaine,strlen(chaine)+1);
- while (ok){
- taille=read(desc2,chaine,1024); //reception numero action
- choix_action=atoi(chaine);
- switch(choix_action){
- case 1:
- result=consulter(numero_compte);
- sprintf(chaine,"%d",result);
- write(desc2,chaine,strlen(chaine)+1);
- printf("Consultation solde pour le compte n°%d: %d\n\n",numero_compte,result);
- break;
- case 2:
- taille=read(desc2,chaine,1024); //reception montant a crediter
- valeur=atoi(chaine);
- printf("Nouveau solde pour le compte n°%d: %d\n\n",numero_compte,result);
- result=ajouter(numero_compte,valeur);
- /*synchronisation: MAJ */
- if(result>=0){
- sprintf(maj,"MAJ:%d:%d",numero_compte,solde[numero_compte]);
- envoiMAJ(maj);
- }
- sprintf(chaine,"%d",result);
- write(desc2,chaine,strlen(chaine)+1); //envoi du resultat
- break;
- case 3:
- taille=read(desc2,chaine,1024); //reception montant a débiter
- valeur=atoi(chaine);
- printf("Nouveau solde pour le compte n°%d: %d\n\n",numero_compte,result);
- result=retirer(numero_compte,valeur);
- /*synchronisation: MAJ */
- if(result>=0){
- sprintf(maj,"MAJ:%d:%d",numero_compte,solde[numero_compte]);
- envoiMAJ(maj);
- }
- sprintf(chaine,"%d",result);
- write(desc2,chaine,strlen(chaine)+1); //envoi du resultat
- break;
- default:
- ok=0;
- printf("FIN de session\n*************\n\n\n");
- break;
- }
- }
- close(desc2);
- }
- pthread_join(thread0, NULL);
- }
- void* receptionMAJ(void* data){
- int sdr, len_r, cnt;
- int new_numero, new_solde;
- char buf[128];
- int r, reuse = 1;
- char *ptr;
- struct sockaddr_in sock_r;
- /*
- * allocation de la structure imr
- */
- struct ip_mreq imr;
- /*
- * initialisation de la structure imr
- */
- imr.imr_multiaddr.s_addr = inet_addr(GROUP);
- imr.imr_interface.s_addr = htonl(INADDR_ANY);
- sdr = socket(PF_INET, SOCK_DGRAM, 0);
- if (sdr < 0) {
- perror("socket");
- exit(1);
- }
- /*
- * initialisation de la socket de reception
- */
- memset(&sock_r, 0, sizeof(sock_r));
- sock_r.sin_family = AF_INET;
- sock_r.sin_port = htons(PORT);
- sock_r.sin_addr.s_addr = htonl(INADDR_ANY);
- len_r = sizeof(sock_r);
- /*on rejoint le groupe*/
- if (setsockopt(sdr, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *) &imr, sizeof(struct ip_mreq)) < 0) {
- perror("setsockopt - IP_ADD_MEMBERSHIP");
- exit(1);
- }
- /*permet la réutiliation du meme port pour tous les serveurs */
- r = setsockopt(sdr, SOL_SOCKET, SO_REUSEADDR, (int *)&reuse, sizeof(reuse));
- if (r == -1) {
- perror("setsockopt: SO_REUSEADDR");
- }
- /*
- * opération bind
- */
- if (bind(sdr, (struct sockaddr *)&sock_r, sizeof(sock_r)) < 0) {
- perror("bind");
- exit(1);
- }
- /*
- * réception des datagrammes et mise à jour
- */
- while (1) {
- cnt = recvfrom(sdr, buf, sizeof(buf), 0, (struct sockaddr *)&sock_r, &len_r);
- if (cnt < 0) {
- perror("recvfrom");
- exit(1);
- }
- buf[strlen(buf)-1]='\0';
- printf("reception MAJ: %s\n", buf); /* affichage du message */
- ptr = strtok(buf, ":");
- if(strcmp(ptr,"MAJ")==0){ /*si le permier mot est MAJ */
- ptr = strtok(NULL, ":"); /*numero compte de la MAJ*/
- new_numero=atoi(ptr);
- ptr = strtok(NULL, ":"); /*nouveau solde*/
- new_solde=atoi(ptr);
- solde[new_numero]=new_solde; /*on effectue la mise a jour*/
- }
- }
- close(sdr);
- }
- void envoiMAJ(char * info){
- int sdw, len_w, cnt;
- int r, reuse = 1;
- struct sockaddr_in sock_w;
- unsigned char ttl = 1;
- /*
- * allocation de la structure imr
- */
- struct ip_mreq imr;
- /*
- * initialisation de la structure imr
- */
- imr.imr_multiaddr.s_addr = inet_addr(GROUP);
- imr.imr_interface.s_addr = htonl(INADDR_ANY);
- sdw = socket(PF_INET, SOCK_DGRAM, 0);
- if (sdw < 0) {
- perror("socket");
- exit(1);
- }
- r=setsockopt(sdw, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
- if (r == -1) {
- perror("setsockopt: IP_MULTICAST_TTL");
- }
- /*
- * initialisation de la socket d'emission
- */
- memset(&sock_w, 0, sizeof(sock_w));
- sock_w.sin_family = AF_INET;
- sock_w.sin_port = htons(PORT);
- sock_w.sin_addr.s_addr = inet_addr(GROUP);
- len_w = sizeof(sock_w);
- /*on rejoint le groupe*/
- if (setsockopt(sdw, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *) &imr, sizeof(struct ip_mreq)) < 0) {
- perror("setsockopt - IP_ADD_MEMBERSHIP");
- exit(1);
- }
- /*permet la réutiliation du meme port pour tous les serveurs */
- r = setsockopt(sdw, SOL_SOCKET, SO_REUSEADDR, (int *)&reuse, sizeof(reuse));
- if (r == -1) {
- perror("setsockopt: SO_REUSEADDR");
- }
- /*
- * opération bind
- */
- if (bind(sdw, (struct sockaddr *)&sock_w, sizeof(sock_w)) < 0) {
- perror("bind");
- exit(1);
- }
- /*
- * emission des datagrammes
- */
- cnt = sendto(sdw, info, strlen(info), 0, (struct sockaddr *)&sock_w, len_w);
- if (cnt < 0) {
- perror("sendto");
- exit(1);
- }
- close(sdw);
- }
- void init(void){
- int i;
- for(i=0;i<NB_COMPTE/2;i++){
- solde[2*i+1]=rand()%1000;
- solde[2*i]=-1; // -1 = compte non créé
- }
- }
- int consulter (int compte){
- if(solde[compte]==-1){
- solde[compte]=0;
- return -1;
- }
- return solde[compte];
- }
- int ajouter (int compte, int valeur){
- consulter(compte);
- solde[compte]+=valeur;
- return solde[compte];
- }
- int retirer (int compte, int valeur){
- int solde_courant=consulter(compte);
- if(solde_courant>=valeur){
- solde[compte]-=valeur;
- return solde[compte];
- }
- return -2; /*code erreur lorsque solde insuffisant*/
- }
Add Comment
Please, Sign In to add comment