Advertisement
Guest User

Untitled

a guest
Oct 28th, 2016
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.86 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <iostream>
  5. #include <unistd.h>
  6. #include <sstream>
  7. #include <errno.h>
  8. #include <string.h> //(memset,)
  9. #include <sys/socket.h>
  10. #include <netinet/in.h>
  11. #include <arpa/inet.h>
  12. #define PORT 65530
  13. #define BACKLOG 10
  14. #include <time.h>
  15. //g++ thread_posix_tcp3.cpp -lpthread -o thread_posix_tcp3.o
  16. //learning mutli threading
  17. //todo:
  18. // parameterize listen port
  19. // bounds checking socket vars
  20. // !stresstest hanging threads
  21. // timeout socket accept
  22. // !idle thread
  23. // catch ctrl-c and shutdown scoket gracefully
  24. // heartbeat? todo: imei nr check
  25. // implement COBAN fully
  26.  
  27. //define posix thread "idle"
  28. pthread_t idleThr;
  29.  
  30. //structure of three floats: N/E and speed
  31. struct threeInts{
  32.         double N,E;
  33.         float sp;
  34. };
  35.  
  36. //returns structure from tracker response string. Call: struct threeInts test;test=returnNEsp(s);
  37. struct threeInts returnNEsp(char s[200]){
  38.         //define structure and set values
  39.         struct threeInts NEsp;
  40.         const char* p;
  41.         int cnt=0;
  42.         for (p = strtok( s, "," );  p;  p = strtok( NULL, "," ))
  43.         {
  44.           if(cnt==7)
  45.                 NEsp.N=atof(p);
  46.           if(cnt==9)
  47.                 NEsp.E=atof(p);
  48.           if(cnt==11)
  49.                 NEsp.sp=atof(p);
  50.           ++cnt;
  51.         }
  52.         return NEsp;
  53. }
  54.  
  55. void *idleThread(void *arg){
  56.     //printf("We are now in idleThread..\n");
  57.     int i;
  58.     for(i=0;i<60;++i){
  59.         //printf("\tIdlesec %i\n",i);
  60.         sleep(1);
  61.     }
  62.     pthread_exit(NULL);
  63. }
  64.  
  65. pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;
  66. int totThr=2;
  67. int thrCnt=totThr;
  68. struct socket_structure{
  69.     int welcomeSocket;
  70.     struct sockaddr_storage serverStorage;
  71.     int *thrCnt;
  72. };
  73.  
  74. void *communicate(void *arg1);
  75.  
  76. int main(int argc, char *argv[]){
  77.     int portnr=7778;
  78.     pthread_t thread1[totThr];
  79.     int welcomeSocket;
  80.     struct sockaddr_in serverAddr;
  81.     struct sockaddr_storage serverStorage;
  82.     socklen_t addr_size;
  83.    
  84.     welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
  85.     serverAddr.sin_family = AF_INET;
  86.     serverAddr.sin_port = htons(portnr);
  87.     serverAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
  88.     memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);  
  89.     bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
  90.     //Listen on the socket, with totThr max connection requests queued
  91.     if(listen(welcomeSocket,totThr)==0)
  92.       printf("Listening in port %i\n",portnr);
  93.     else
  94.       printf("Error\n");
  95.     addr_size = sizeof serverStorage;
  96.  
  97.     //define vars
  98.     int cnt=0;
  99.     int start=1;
  100.     //structure needed to start thread and pass multiple parameters
  101.     struct socket_structure SS;
  102.     SS.welcomeSocket=welcomeSocket;
  103.     SS.serverStorage=serverStorage;
  104.     SS.thrCnt=&thrCnt;
  105.     int rc;
  106.     //start initial threads
  107.     if(start==1){
  108.         int j;
  109.         for(j=0;j<totThr;++j){
  110.             rc=pthread_create( &thread1[j], NULL, communicate, (void*) &SS);
  111.             if (rc == 0){
  112.                 //printf("thread[%i] created.. detaching ",j);
  113.                     rc = pthread_detach(thread1[j]);
  114.                 if(rc!=0)
  115.                     printf("failed..\n");
  116.             }
  117.         }
  118.         start=0;
  119.     }
  120.     //main loop
  121.     for(;;){
  122.         //if threadcnt eq total threads, start idlethread function
  123.         if(thrCnt==totThr){
  124.             //call idleThread, we have enough threads
  125.             rc=pthread_create( &idleThr, NULL, idleThread, (void*) NULL);
  126.             pthread_join(idleThr, NULL);
  127.         }
  128.         //threads lower than totThr.. start new threads
  129.         if(thrCnt<totThr){
  130.             pthread_mutex_lock(&a_mutex); //lock mutex for thrCnt
  131.             while(thrCnt < totThr){
  132.                 rc=pthread_create( &thread1[thrCnt], NULL, communicate, (void*) &SS);
  133.                 if (rc == 0){
  134.                     //detach newly created thread
  135.                         rc = pthread_detach(thread1[thrCnt]);
  136.                     if(rc!=0){
  137.                         printf("failed..\n");
  138.                     }else{
  139.                         ++thrCnt;
  140.                     }
  141.                 }
  142.             }
  143.             pthread_mutex_unlock(&a_mutex);//unlock mutex
  144.         }
  145.         ++cnt;
  146.     }
  147.  
  148.     pthread_exit(NULL);
  149. }
  150.  
  151. void *communicate(void *arg1){
  152.     char buffert[200]; //strcpy(buffert,"");
  153.     char response[200];
  154.     pthread_t id = pthread_self();
  155.     struct socket_structure *SS;
  156.     SS=(struct socket_structure*)arg1;
  157.     socklen_t addr_size;addr_size= sizeof SS->serverStorage;
  158.    
  159.     //accept connection
  160.     int newSocket = accept(SS->welcomeSocket, (struct sockaddr *) &SS->serverStorage, &addr_size);
  161.  
  162.     //mutex and decrement thread counter
  163.     pthread_mutex_lock(&a_mutex);
  164.     --*SS->thrCnt;
  165.     pthread_mutex_unlock(&a_mutex);
  166.  
  167.     //receive auth
  168.     if (!recv(newSocket, response, 30,0)) {
  169.         close(newSocket);
  170.         pthread_cancel(idleThr);
  171.         int retcode=200;
  172.         pthread_exit(&retcode);
  173.         }
  174.    
  175.     if(bcmp("##,imei:868683024944313,A;",response,26) == 0){
  176.         strcpy(buffert,"LOAD\n");
  177.     }else{
  178.         //failed auth, exit comm thread
  179.         strcpy(buffert,"NOPE\n");
  180.         close(newSocket);
  181.         pthread_cancel(idleThr);
  182.         int retcode=200;
  183.         pthread_exit(&retcode);
  184.     }
  185.     memset(response,0,sizeof(response));
  186.     send(newSocket,buffert,6,0);
  187.  
  188.     //server request Multiple position, every 1 minutes **,imei:359446018966098,C,1m   
  189.     strcpy(buffert,"**,imei:3544446018966098,C,1m\n");
  190.     send(newSocket,buffert,30,0);
  191.     memset(buffert,0,sizeof(buffert));
  192.  
  193.     //receive responses again
  194.     while(true) {
  195.         if(recv(newSocket, response, 1024,0)){
  196.             if(bcmp("imei",response,4)==0){
  197.                 //get N/E and speed
  198.                 struct threeInts NEsp=returnNEsp(response);
  199.                 printf("Tracker reported N: %.4f, E: %.4f speed: %.2f\n",NEsp.N,NEsp.E,NEsp.sp);
  200.                
  201.                 //todo: write to tracking file
  202.                
  203.             }else{
  204.                 //heartbeat? todo: imei nr check or else disconnect client
  205.                 printf("Responding 'ON' to hearbeat request\n");
  206.                 strcpy(buffert,"ON\n");
  207.                     send(newSocket,buffert,10,0);
  208.             }
  209.             memset(response,0,sizeof(response));
  210.             memset(buffert,0,sizeof(buffert));
  211.         }
  212.         sleep(1);
  213.         }
  214.     strcpy(buffert,"ok bynow\n");
  215.     send(newSocket,buffert,10,0);
  216.  
  217.     memset(response,0,sizeof(response));
  218.    
  219.     close(newSocket);
  220.     //printf("\tExiting communication thread\n");
  221.     pthread_cancel(idleThr);
  222.     pthread_exit(NULL);
  223.     return NULL;
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement