Guest User

Untitled

a guest
Apr 22nd, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.45 KB | None | 0 0
  1. #include <sys/socket.h>
  2. #include <sys/types.h>
  3. #include <arpa/inet.h>
  4. #include <unistd.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <stdio.h>
  8. #include <math.h>
  9. #include <netinet/in.h>
  10. #include <netdb.h>
  11. #include <pthread.h>
  12.  
  13. #define NB_COMPTE 100
  14. #define GROUP "224.17.11.11"
  15. #define PORT 55501
  16.  
  17. void init(void);
  18. int consulter (int compte);
  19. int ajouter (int compte, int valeur);
  20. int retirer (int compte, int valeur);
  21. void* receptionMAJ(void* data);
  22. void envoiMAJ(char * info);
  23.  
  24. int solde[NB_COMPTE];
  25.  
  26. int main ( int argc, char *argv[]){
  27.  
  28. int numero_compte;
  29. int choix_action;
  30. int result;
  31. int valeur;
  32. int ok;
  33. int code;
  34. int desc,desc2,taille;
  35. int longueur=sizeof(struct sockaddr_in);
  36. char chaine[1024];
  37. char maj[1024];
  38. struct sockaddr_in adr1,adr2;
  39.  
  40. /*test nombre de parametres*/
  41. if (argc != 2){
  42. perror("Erreur: nombre de parametres incorrect\n\t=>(argv[1]=port) ");
  43. return -1;
  44. }
  45.  
  46. init();
  47.  
  48. /* initialisation et début connection tcp */
  49. if((desc=socket(AF_INET,SOCK_STREAM,0)) == -1)
  50. {
  51. perror("socket ...");exit(1);
  52. }
  53.  
  54. adr1.sin_family=AF_INET;
  55. adr1.sin_addr.s_addr=htonl(INADDR_ANY);
  56. adr1.sin_port=htons(atoi(argv[1]));
  57.  
  58. if(bind(desc,(struct sockaddr *)&adr1,longueur)==-1)
  59. {
  60. perror("bind ...");exit(1);
  61. }
  62.  
  63. if(listen(desc,10)==-1)
  64. {
  65. perror("listen ...");exit(1);
  66. }
  67.  
  68. /* fin de l'iniitalisation tcp */
  69.  
  70. /*lancement du thread découte udp */
  71. pthread_t thread0;// On crée un thread
  72. pthread_create(&thread0, NULL, receptionMAJ, NULL);
  73.  
  74. while(1){
  75. if((desc2=accept(desc,(struct sockaddr *)&adr2,&longueur))==-1)
  76. {
  77. perror("bind ...");exit(1);
  78. }
  79. ok=1;
  80.  
  81. taille=read(desc2,chaine,1024); //reception numero compte
  82. numero_compte=atoi(chaine);
  83.  
  84. printf("Operation sur le compte Numero: %d\n",numero_compte);
  85.  
  86. if(numero_compte >NB_COMPTE){
  87. ok=0;
  88. code=-2;
  89. }
  90. if((consulter(numero_compte)==-1)&&(ok==1)){
  91. code=-1;
  92. }
  93. code =0;
  94.  
  95. sprintf(chaine,"%d",code);
  96. write(desc2,chaine,strlen(chaine)+1);
  97.  
  98. while (ok){
  99. taille=read(desc2,chaine,1024); //reception numero action
  100. choix_action=atoi(chaine);
  101. switch(choix_action){
  102. case 1:
  103. result=consulter(numero_compte);
  104. sprintf(chaine,"%d",result);
  105. write(desc2,chaine,strlen(chaine)+1);
  106. printf("Consultation solde pour le compte n°%d: %d\n\n",numero_compte,result);
  107. break;
  108. case 2:
  109. taille=read(desc2,chaine,1024); //reception montant a crediter
  110. valeur=atoi(chaine);
  111.  
  112. printf("Nouveau solde pour le compte n°%d: %d\n\n",numero_compte,result);
  113. result=ajouter(numero_compte,valeur);
  114.  
  115. /*synchronisation: MAJ */
  116. if(result>=0){
  117. sprintf(maj,"MAJ:%d:%d",numero_compte,solde[numero_compte]);
  118. envoiMAJ(maj);
  119. }
  120.  
  121. sprintf(chaine,"%d",result);
  122. write(desc2,chaine,strlen(chaine)+1); //envoi du resultat
  123.  
  124. break;
  125. case 3:
  126. taille=read(desc2,chaine,1024); //reception montant a débiter
  127. valeur=atoi(chaine);
  128. printf("Nouveau solde pour le compte n°%d: %d\n\n",numero_compte,result);
  129. result=retirer(numero_compte,valeur);
  130.  
  131. /*synchronisation: MAJ */
  132. if(result>=0){
  133. sprintf(maj,"MAJ:%d:%d",numero_compte,solde[numero_compte]);
  134. envoiMAJ(maj);
  135. }
  136.  
  137. sprintf(chaine,"%d",result);
  138. write(desc2,chaine,strlen(chaine)+1); //envoi du resultat
  139. break;
  140. default:
  141. ok=0;
  142. printf("FIN de session\n*************\n\n\n");
  143. break;
  144. }
  145. }
  146. close(desc2);
  147. }
  148. pthread_join(thread0, NULL);
  149. }
  150.  
  151. void* receptionMAJ(void* data){
  152.  
  153. int sdr, len_r, cnt;
  154. int new_numero, new_solde;
  155. char buf[128];
  156. int r, reuse = 1;
  157. char *ptr;
  158. struct sockaddr_in sock_r;
  159.  
  160. /*
  161. * allocation de la structure imr
  162. */
  163. struct ip_mreq imr;
  164.  
  165. /*
  166. * initialisation de la structure imr
  167. */
  168. imr.imr_multiaddr.s_addr = inet_addr(GROUP);
  169. imr.imr_interface.s_addr = htonl(INADDR_ANY);
  170.  
  171. sdr = socket(PF_INET, SOCK_DGRAM, 0);
  172. if (sdr < 0) {
  173. perror("socket");
  174. exit(1);
  175. }
  176.  
  177. /*
  178. * initialisation de la socket de reception
  179. */
  180. memset(&sock_r, 0, sizeof(sock_r));
  181. sock_r.sin_family = AF_INET;
  182. sock_r.sin_port = htons(PORT);
  183. sock_r.sin_addr.s_addr = htonl(INADDR_ANY);
  184.  
  185. len_r = sizeof(sock_r);
  186.  
  187. /*on rejoint le groupe*/
  188. if (setsockopt(sdr, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *) &imr, sizeof(struct ip_mreq)) < 0) {
  189. perror("setsockopt - IP_ADD_MEMBERSHIP");
  190. exit(1);
  191. }
  192.  
  193. /*permet la réutiliation du meme port pour tous les serveurs */
  194. r = setsockopt(sdr, SOL_SOCKET, SO_REUSEADDR, (int *)&reuse, sizeof(reuse));
  195. if (r == -1) {
  196. perror("setsockopt: SO_REUSEADDR");
  197. }
  198.  
  199. /*
  200. * opération bind
  201. */
  202. if (bind(sdr, (struct sockaddr *)&sock_r, sizeof(sock_r)) < 0) {
  203. perror("bind");
  204. exit(1);
  205. }
  206.  
  207. /*
  208. * réception des datagrammes et mise à jour
  209. */
  210. while (1) {
  211. cnt = recvfrom(sdr, buf, sizeof(buf), 0, (struct sockaddr *)&sock_r, &len_r);
  212. if (cnt < 0) {
  213. perror("recvfrom");
  214. exit(1);
  215. }
  216. buf[strlen(buf)-1]='\0';
  217. printf("reception MAJ: %s\n", buf); /* affichage du message */
  218. ptr = strtok(buf, ":");
  219. if(strcmp(ptr,"MAJ")==0){ /*si le permier mot est MAJ */
  220. ptr = strtok(NULL, ":"); /*numero compte de la MAJ*/
  221. new_numero=atoi(ptr);
  222. ptr = strtok(NULL, ":"); /*nouveau solde*/
  223. new_solde=atoi(ptr);
  224. solde[new_numero]=new_solde; /*on effectue la mise a jour*/
  225. }
  226. }
  227. close(sdr);
  228. }
  229.  
  230.  
  231.  
  232. void envoiMAJ(char * info){
  233.  
  234. int sdw, len_w, cnt;
  235. int r, reuse = 1;
  236. struct sockaddr_in sock_w;
  237. unsigned char ttl = 1;
  238. /*
  239. * allocation de la structure imr
  240. */
  241. struct ip_mreq imr;
  242.  
  243. /*
  244. * initialisation de la structure imr
  245. */
  246. imr.imr_multiaddr.s_addr = inet_addr(GROUP);
  247. imr.imr_interface.s_addr = htonl(INADDR_ANY);
  248.  
  249.  
  250. sdw = socket(PF_INET, SOCK_DGRAM, 0);
  251. if (sdw < 0) {
  252. perror("socket");
  253. exit(1);
  254. }
  255.  
  256. r=setsockopt(sdw, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
  257. if (r == -1) {
  258. perror("setsockopt: IP_MULTICAST_TTL");
  259. }
  260.  
  261. /*
  262. * initialisation de la socket d'emission
  263. */
  264. memset(&sock_w, 0, sizeof(sock_w));
  265. sock_w.sin_family = AF_INET;
  266. sock_w.sin_port = htons(PORT);
  267. sock_w.sin_addr.s_addr = inet_addr(GROUP);
  268.  
  269.  
  270. len_w = sizeof(sock_w);
  271.  
  272. /*on rejoint le groupe*/
  273. if (setsockopt(sdw, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *) &imr, sizeof(struct ip_mreq)) < 0) {
  274. perror("setsockopt - IP_ADD_MEMBERSHIP");
  275. exit(1);
  276. }
  277.  
  278. /*permet la réutiliation du meme port pour tous les serveurs */
  279. r = setsockopt(sdw, SOL_SOCKET, SO_REUSEADDR, (int *)&reuse, sizeof(reuse));
  280. if (r == -1) {
  281. perror("setsockopt: SO_REUSEADDR");
  282. }
  283.  
  284. /*
  285. * opération bind
  286. */
  287. if (bind(sdw, (struct sockaddr *)&sock_w, sizeof(sock_w)) < 0) {
  288. perror("bind");
  289. exit(1);
  290. }
  291.  
  292. /*
  293. * emission des datagrammes
  294. */
  295. cnt = sendto(sdw, info, strlen(info), 0, (struct sockaddr *)&sock_w, len_w);
  296. if (cnt < 0) {
  297. perror("sendto");
  298. exit(1);
  299. }
  300. close(sdw);
  301. }
  302.  
  303.  
  304.  
  305. void init(void){
  306. int i;
  307. for(i=0;i<NB_COMPTE/2;i++){
  308. solde[2*i+1]=rand()%1000;
  309. solde[2*i]=-1; // -1 = compte non créé
  310. }
  311. }
  312.  
  313. int consulter (int compte){
  314. if(solde[compte]==-1){
  315. solde[compte]=0;
  316. return -1;
  317. }
  318. return solde[compte];
  319. }
  320.  
  321.  
  322. int ajouter (int compte, int valeur){
  323. consulter(compte);
  324. solde[compte]+=valeur;
  325. return solde[compte];
  326. }
  327.  
  328.  
  329. int retirer (int compte, int valeur){
  330. int solde_courant=consulter(compte);
  331. if(solde_courant>=valeur){
  332. solde[compte]-=valeur;
  333. return solde[compte];
  334. }
  335. return -2; /*code erreur lorsque solde insuffisant*/
  336. }
Add Comment
Please, Sign In to add comment