Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <pthread.h>
- #include <iostream>
- #include <unistd.h>
- #include <sstream>
- #include <errno.h>
- #include <string.h> //(memset,)
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #define PORT 65530
- #define BACKLOG 10
- #include <time.h>
- //g++ thread_posix_tcp3.cpp -lpthread -o thread_posix_tcp3.o
- //learning mutli threading
- //todo:
- // parameterize listen port
- // bounds checking socket vars
- // !stresstest hanging threads
- // timeout socket accept
- // !idle thread
- // catch ctrl-c and shutdown scoket gracefully
- // heartbeat? todo: imei nr check
- // implement COBAN fully
- //define posix thread "idle"
- pthread_t idleThr;
- //structure of three floats: N/E and speed
- struct threeInts{
- double N,E;
- float sp;
- };
- //returns structure from tracker response string. Call: struct threeInts test;test=returnNEsp(s);
- struct threeInts returnNEsp(char s[200]){
- //define structure and set values
- struct threeInts NEsp;
- const char* p;
- int cnt=0;
- for (p = strtok( s, "," ); p; p = strtok( NULL, "," ))
- {
- if(cnt==7)
- NEsp.N=atof(p);
- if(cnt==9)
- NEsp.E=atof(p);
- if(cnt==11)
- NEsp.sp=atof(p);
- ++cnt;
- }
- return NEsp;
- }
- void *idleThread(void *arg){
- //printf("We are now in idleThread..\n");
- int i;
- for(i=0;i<60;++i){
- //printf("\tIdlesec %i\n",i);
- sleep(1);
- }
- pthread_exit(NULL);
- }
- pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER;
- int totThr=2;
- int thrCnt=totThr;
- struct socket_structure{
- int welcomeSocket;
- struct sockaddr_storage serverStorage;
- int *thrCnt;
- };
- void *communicate(void *arg1);
- int main(int argc, char *argv[]){
- int portnr=7778;
- pthread_t thread1[totThr];
- int welcomeSocket;
- struct sockaddr_in serverAddr;
- struct sockaddr_storage serverStorage;
- socklen_t addr_size;
- welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
- serverAddr.sin_family = AF_INET;
- serverAddr.sin_port = htons(portnr);
- serverAddr.sin_addr.s_addr = inet_addr("0.0.0.0");
- memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
- bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
- //Listen on the socket, with totThr max connection requests queued
- if(listen(welcomeSocket,totThr)==0)
- printf("Listening in port %i\n",portnr);
- else
- printf("Error\n");
- addr_size = sizeof serverStorage;
- //define vars
- int cnt=0;
- int start=1;
- //structure needed to start thread and pass multiple parameters
- struct socket_structure SS;
- SS.welcomeSocket=welcomeSocket;
- SS.serverStorage=serverStorage;
- SS.thrCnt=&thrCnt;
- int rc;
- //start initial threads
- if(start==1){
- int j;
- for(j=0;j<totThr;++j){
- rc=pthread_create( &thread1[j], NULL, communicate, (void*) &SS);
- if (rc == 0){
- //printf("thread[%i] created.. detaching ",j);
- rc = pthread_detach(thread1[j]);
- if(rc!=0)
- printf("failed..\n");
- }
- }
- start=0;
- }
- //main loop
- for(;;){
- //if threadcnt eq total threads, start idlethread function
- if(thrCnt==totThr){
- //call idleThread, we have enough threads
- rc=pthread_create( &idleThr, NULL, idleThread, (void*) NULL);
- pthread_join(idleThr, NULL);
- }
- //threads lower than totThr.. start new threads
- if(thrCnt<totThr){
- pthread_mutex_lock(&a_mutex); //lock mutex for thrCnt
- while(thrCnt < totThr){
- rc=pthread_create( &thread1[thrCnt], NULL, communicate, (void*) &SS);
- if (rc == 0){
- //detach newly created thread
- rc = pthread_detach(thread1[thrCnt]);
- if(rc!=0){
- printf("failed..\n");
- }else{
- ++thrCnt;
- }
- }
- }
- pthread_mutex_unlock(&a_mutex);//unlock mutex
- }
- ++cnt;
- }
- pthread_exit(NULL);
- }
- void *communicate(void *arg1){
- char buffert[200]; //strcpy(buffert,"");
- char response[200];
- pthread_t id = pthread_self();
- struct socket_structure *SS;
- SS=(struct socket_structure*)arg1;
- socklen_t addr_size;addr_size= sizeof SS->serverStorage;
- //accept connection
- int newSocket = accept(SS->welcomeSocket, (struct sockaddr *) &SS->serverStorage, &addr_size);
- //mutex and decrement thread counter
- pthread_mutex_lock(&a_mutex);
- --*SS->thrCnt;
- pthread_mutex_unlock(&a_mutex);
- //receive auth
- if (!recv(newSocket, response, 30,0)) {
- close(newSocket);
- pthread_cancel(idleThr);
- int retcode=200;
- pthread_exit(&retcode);
- }
- if(bcmp("##,imei:868683024944313,A;",response,26) == 0){
- strcpy(buffert,"LOAD\n");
- }else{
- //failed auth, exit comm thread
- strcpy(buffert,"NOPE\n");
- close(newSocket);
- pthread_cancel(idleThr);
- int retcode=200;
- pthread_exit(&retcode);
- }
- memset(response,0,sizeof(response));
- send(newSocket,buffert,6,0);
- //server request Multiple position, every 1 minutes **,imei:359446018966098,C,1m
- strcpy(buffert,"**,imei:3544446018966098,C,1m\n");
- send(newSocket,buffert,30,0);
- memset(buffert,0,sizeof(buffert));
- //receive responses again
- while(true) {
- if(recv(newSocket, response, 1024,0)){
- if(bcmp("imei",response,4)==0){
- //get N/E and speed
- struct threeInts NEsp=returnNEsp(response);
- printf("Tracker reported N: %.4f, E: %.4f speed: %.2f\n",NEsp.N,NEsp.E,NEsp.sp);
- //todo: write to tracking file
- }else{
- //heartbeat? todo: imei nr check or else disconnect client
- printf("Responding 'ON' to hearbeat request\n");
- strcpy(buffert,"ON\n");
- send(newSocket,buffert,10,0);
- }
- memset(response,0,sizeof(response));
- memset(buffert,0,sizeof(buffert));
- }
- sleep(1);
- }
- strcpy(buffert,"ok bynow\n");
- send(newSocket,buffert,10,0);
- memset(response,0,sizeof(response));
- close(newSocket);
- //printf("\tExiting communication thread\n");
- pthread_cancel(idleThr);
- pthread_exit(NULL);
- return NULL;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement