/****************************************************************************** Description.: this is the mflisten thread it loops forever, listen on the src_GUID Input Value.: Return Value: ******************************************************************************/ void *mflisten_thread(void *arg) { if (debug) printf("\nin listen thread\n"); while (!global_stop) { MsgD.listen(); } return NULL; }
/****************************************************************************** Description.: print out the error message and exit Input Value.: Return Value: ******************************************************************************/ void errorSocket(const char *msg, int sock) { errno = EBADF; perror(msg); if (!orbit) { close(sock); } else { MsgD.close(sock, 1); } printf("[server] Connection closed. --- error\n\n"); pthread_exit(NULL); //terminate calling thread! }
/****************************************************************************** Description.: There is a separate instance of this function for each connection. It handles all communication once a connnection has been established. Input Value.: Return Value: - ******************************************************************************/ void *serverThread (void * inputsock) { int sock = *((int *)inputsock); int n; char buffer[100]; string userID; char *threadType; char fail[] = "failed"; // Receive the header bzero(buffer, sizeof(buffer)); if (!orbit) { n = read(sock, buffer, sizeof(buffer)); if (n < 0) { errorSocket("ERROR reading from socket", sock); } } // below is orbit mode, using MFAPI else { MsgD.recv(sock, buffer, sizeof(buffer)); } printf("[server] header content: %s\n\n",buffer); threadType = strtok(buffer, ","); userID = strtok(NULL, ","); // grap the lock pthread_mutex_lock(&user_map_lock); // confirm that this user does not log in if (user_map.find(userID) == user_map.end()) { // put the new user into user map user_map[userID] = 1; } else { if (user_map[userID] == 1) { // increase user thread count user_map[userID] = 2; } else { // remember to unlock! pthread_mutex_unlock(&user_map_lock); // reponse to the client if (!orbit) { if (write(sock, "failed", sizeof("failed")) < 0) { errorSocket("ERROR writting to socket", sock); } close(sock); } else { MsgD.send(sock, fail, sizeof(fail)); } printf("[server] User exist. Connection closed.\n\n"); return 0; } } pthread_mutex_unlock(&user_map_lock); if (strcmp(threadType, "transmit") == 0) { server_transmit(sock, userID); } else if (strcmp(threadType, "result") == 0) { server_result(sock, userID); } else { if (!orbit) { close(sock); } printf("[server] Command Unknown. Connection closed.\n\n"); } return 0; }
/****************************************************************************** Description: function for transmitting the frames Input Value.: Return Value: ******************************************************************************/ void server_transmit (int sock, string userID) { // printf("transmitting part\n"); int n; char response[] = "ok"; char file_name_temp[60]; char *file_name; int write_length = 0; int length = 0; queue<string> *imgQueue = new queue<string>(); // queue storing the file names // grap the lock pthread_mutex_lock(&queue_map_lock); queue_map[userID] = imgQueue; // put the address of queue into map pthread_mutex_unlock(&queue_map_lock); pthread_mutex_t queueLock; // mutex lock for queue operation sem_t *sem_match = 0; // init the mutex lock if (pthread_mutex_init(&queueLock, NULL) != 0) { errorSocket("ERROR mutex init failed", sock); } if (!orbit) { char buffer[BUFFER_SIZE]; char *file_size_char; int file_size; int received_size = 0; // reponse to the client n = write(sock, response, sizeof(response)); if (n < 0) { pthread_mutex_destroy(&queueLock); errorSocket("ERROR writting to socket", sock); } while (!global_stop) { received_size = 0; // receive the file info bzero(buffer, sizeof(buffer)); n = read(sock,buffer, sizeof(buffer)); if (n <= 0) { pthread_mutex_destroy(&queueLock); // signal the result thread to terminate sem_post(sem_match); errorSocket("ERROR reading from socket", sock); } // store the file name and the block count file_name = strtok(buffer, ","); strcpy(file_name_temp, file_name); if (debug) printf("\n[server] file name: [%s]\n", file_name); file_size_char = strtok(NULL, ","); file_size = strtol(file_size_char, NULL, 10); if (debug) printf("file size: %d\n", file_size); // calculate the time consumption here struct timeval tpstart,tpend; double timeuse; gettimeofday(&tpstart,NULL); // reponse to the client n = write(sock, response, sizeof(response)); if (n <= 0) { pthread_mutex_destroy(&queueLock); // signal the result thread to terminate sem_post(sem_match); errorSocket("ERROR writting to socket", sock); } if (!storm) { FILE *fp = fopen(file_name, "w"); if (fp == NULL) { printf("File:\t%s Can Not Open To Write!\n", file_name); break; } int done = 0; // receive the data from client and store them into buffer bzero(buffer, sizeof(buffer)); while((length = recv(sock, buffer, sizeof(buffer), 0))) { if (length < 0) { printf("Recieve Data From Client Failed!\n"); break; } int remain = file_size - received_size; if (remain < BUFFER_SIZE) { length = remain; done = 1; } write_length = fwrite(buffer, sizeof(char), length, fp); if (write_length < length) { printf("File:\t Write Failed!\n"); break; } bzero(buffer, sizeof(buffer)); if (done) { if (debug) printf("file size full\n"); break; } received_size += length; } // print out time comsumption gettimeofday(&tpend,NULL); timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_usec;// notice, should include both s and us // printf("used time:%fus\n",timeuse); printf("receive used time:%fms\n",timeuse / 1000); if (debug) printf("[server] Recieve Finished!\n\n"); // finished fclose(fp); } // below is storm mode else { // in storm mode, don't save img into disk int offset = 0; char* img = new char[file_size]; int done = 0; // receive the data from server and store them into buffer bzero(buffer, sizeof(buffer)); while((length = recv(sock, buffer, sizeof(buffer), 0))) { if (length < 0) { printf("Recieve Data From Client Failed!\n"); break; } int remain = file_size - offset; if (remain < BUFFER_SIZE) { length = remain; done = 1; } // copy the content into img for (int i = 0; i < length; ++i) { img[i + offset] = buffer[i]; } bzero(buffer, sizeof(buffer)); if (done) { if (debug) printf("offset: %d\n", offset + remain); if (debug) printf("file size full\n"); break; } offset += length; // if (debug) printf("offset: %d\n", offset); } // print out time comsumption gettimeofday(&tpend,NULL); timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_usec;// notice, should include both s and us // printf("used time:%fus\n",timeuse); printf("receive used time:%fms\n",timeuse / 1000); if (debug) printf("[server] Recieve Finished!\n\n"); // send request to spout if (debug) printf("Now try to connect the spout\n"); int sockfd, ret; int spoutPort = 9878; struct sockaddr_in spout_addr; struct hostent *spout; struct in_addr ipv4addr; char buf_spout[100]; char* spout_IP; const int len = spoutIP.length(); spout_IP = new char[len+1]; strcpy(spout_IP, spoutIP.c_str()); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { printf("ERROR opening socket\n"); return; } inet_pton(AF_INET, spout_IP, &ipv4addr); spout = gethostbyaddr(&ipv4addr, sizeof(ipv4addr), AF_INET); if (debug) printf("\n[server] Spout address: %s\n", spout_IP); if (spout == NULL) { fprintf(stderr,"ERROR, no such host\n"); exit(0); } bzero((char *) &spout_addr, sizeof(spout_addr)); spout_addr.sin_family = AF_INET; bcopy((char *)spout->h_addr, (char *)&spout_addr.sin_addr.s_addr, spout->h_length); spout_addr.sin_port = htons(spoutPort); while (connect(sockfd,(struct sockaddr *) &spout_addr, sizeof(spout_addr)) < 0) { printf("The spout is not available now, wait a while and reconnect\n\n"); usleep(100000); // sleep 100ms } printf("[server] Get connection to spout\n"); bzero(buf_spout, sizeof(buf_spout)); sprintf(buf_spout, "%d", file_size); if (debug) printf("[server] send the file size\n"); ret = write(sockfd, buf_spout, sizeof(buf_spout)); if (ret < 0) { printf("error sending\n"); return; } // get the response bzero(buf_spout, sizeof(buf_spout)); if (debug) printf("[server] now wait for response\n"); ret = read(sockfd, buf_spout, sizeof(buf_spout)); if (ret < 0) { printf("error reading\n"); return; } if (debug) printf("got response: %s\n", buf_spout); if (debug) printf("[server] send the img\n"); ret = write(sockfd, img, file_size); if (ret < 0) { printf("error sending\n"); return; } if (debug) printf("ret: %d\n", ret); printf("[server] Finished transmitting image to spout\n\n"); close(sockfd); delete[] img; } // lock the queue, ensure there is only one thread modifying the queue pthread_mutex_lock(&queueLock); // store the file name to the waiting queue string file_name_string(file_name_temp); imgQueue->push(file_name_string); pthread_mutex_unlock(&queueLock); // get the address of sem_match if (sem_match == 0) { while (sem_map.find(userID) == sem_map.end()); sem_match = sem_map[userID]; } // signal the result thread to do image processing sem_post(sem_match); // pause(); } close(sock); } // below is orbit mode else { // get the id length int id_length = 1; int divisor = 10; while (sock / divisor > 0) { ++id_length; divisor *= 10; } int recv_length = BUFFER_SIZE * 4; // 4096 bytes per time char buffer[recv_length]; char *file_size_char; int file_size; int received_size = 0; if (debug) printf("\nstart receiving file\n"); // reponse to the client MsgD.send(sock, response, sizeof(response)); while (!global_stop) { received_size = 0; bzero(buffer, sizeof(buffer)); // get the file info from client n = MsgD.recv(sock, buffer, 100); if (n < 0) { pthread_mutex_destroy(&queueLock); // signal the result thread to terminate sem_post(sem_match); errorSocket("ERROR reading from socket", sock); return; } file_name = strtok(buffer, ","); strcpy(file_name_temp, file_name); printf("\n[server] file name: [%s]\n", file_name); file_size_char = strtok(NULL, ","); file_size = strtol(file_size_char, NULL, 10); printf("[server] file size: %d\n", file_size); // calculate the time consumption here struct timeval tpstart,tpend; double timeuse; gettimeofday(&tpstart,NULL); // reponse to the client MsgD.send(sock, response, sizeof(response)); // local mode if (!storm) { FILE *fp = fopen(file_name, "w"); if (fp == NULL) { printf("File:\t[%s] Can Not Open To Write!\n", file_name); } // receive the data from server and store them into buffer while(1) { bzero(buffer, sizeof(buffer)); n = MsgD.recv(sock, buffer, sizeof(buffer)); if (n <= 0) { pthread_mutex_destroy(&queueLock); // signal the result thread to terminate sem_post(sem_match); errorSocket("ERROR reading from socket", sock); } if (file_size - received_size <= recv_length) { int remain = file_size - received_size; write_length = fwrite(buffer, sizeof(char), remain, fp); if (write_length < remain) { printf("File:\t Write Failed!\n"); break; } break; } write_length = fwrite(buffer, sizeof(char), recv_length, fp); if (write_length < recv_length) { printf("File:\t Write Failed!\n"); break; } received_size += recv_length; } // print out time comsumption gettimeofday(&tpend,NULL); timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_usec;// notice, should include both s and us // printf("used time:%fus\n",timeuse); printf("receive used time:%fms\n",timeuse / 1000); printf("[server] Recieve Finished!\n\n"); // finished fclose(fp); } // below is storm mode else { // in storm mode, don't save img into disk char* img = new char[file_size]; int offset = 0; // receive the data from client and store them into buffer while(1) { bzero(buffer, sizeof(buffer)); n = MsgD.recv(sock, buffer, sizeof(buffer)); if (n <= 0) { pthread_mutex_destroy(&queueLock); // signal the result thread to terminate sem_post(sem_match); errorSocket("ERROR reading from socket", sock); } if (file_size - received_size <= recv_length) { int remain = file_size - received_size; // copy the content into img for (int i = 0; i < remain; ++i) { img[i + offset] = buffer[i]; } break; } // copy the content into img for (int i = 0; i < recv_length; ++i) { img[i + offset] = buffer[i]; } offset += recv_length; received_size += recv_length; } // print out time comsumption gettimeofday(&tpend,NULL); timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_usec;// notice, should include both s and us // printf("used time:%fus\n",timeuse); printf("receive used time:%fms\n",timeuse / 1000); if (debug) printf("[server] Recieve Finished!\n\n"); // send request to spout if (debug) printf("Now try to connect the spout\n"); int sockfd, ret; int spoutPort = 9878; struct sockaddr_in spout_addr; struct hostent *spout; struct in_addr ipv4addr; char buf_spout[100]; char* spout_IP; const int len = spoutIP.length(); spout_IP = new char[len+1]; strcpy(spout_IP, spoutIP.c_str()); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { printf("ERROR opening socket\n"); return; } inet_pton(AF_INET, spout_IP, &ipv4addr); spout = gethostbyaddr(&ipv4addr, sizeof(ipv4addr), AF_INET); if (debug) printf("\n[server] Spout address: %s\n", spout_IP); if (spout == NULL) { fprintf(stderr,"ERROR, no such host\n"); exit(0); } bzero((char *) &spout_addr, sizeof(spout_addr)); spout_addr.sin_family = AF_INET; bcopy((char *)spout->h_addr, (char *)&spout_addr.sin_addr.s_addr, spout->h_length); spout_addr.sin_port = htons(spoutPort); while (connect(sockfd,(struct sockaddr *) &spout_addr, sizeof(spout_addr)) < 0) { printf("The spout is not available now, wait a while and reconnect\n\n"); usleep(100000); // sleep 100ms } printf("[server] Get connection to spout\n"); bzero(buf_spout, sizeof(buf_spout)); sprintf(buf_spout, "%d", file_size); if (debug) printf("[server] send the file size\n"); ret = write(sockfd, buf_spout, sizeof(buf_spout)); if (ret < 0) { printf("error sending\n"); return; } // get the response bzero(buf_spout, sizeof(buf_spout)); if (debug) printf("[server] now wait for response\n"); ret = read(sockfd, buf_spout, sizeof(buf_spout)); if (ret < 0) { printf("error reading\n"); return; } if (debug) printf("got response: %s\n", buf_spout); if (debug) printf("[server] send the img\n"); ret = write(sockfd, img, file_size); if (ret < 0) { printf("error sending\n"); return; } if (debug) printf("ret: %d\n", ret); printf("[server] Finished transmitting image to spout\n\n"); close(sockfd); delete[] img; } // lock the queue, ensure there is only one thread modifying the queue pthread_mutex_lock(&queueLock); // store the file name to the waiting queue string file_name_string(file_name_temp); imgQueue->push(file_name_string); pthread_mutex_unlock(&queueLock); // get the address of sem_match if (sem_match == 0) { while (sem_map.find(userID) == sem_map.end()); sem_match = sem_map[userID]; } // signal the result thread to do image processing sem_post(sem_match); } } delete(imgQueue); printf("[server] Connection closed. --- transmit\n\n"); // pthread_exit(NULL); //terminate calling thread! return; }
/****************************************************************************** Description: function for sending back the result Input Value.: Return Value: ******************************************************************************/ void server_result (int sock, string userID) { if (debug) printf("result thread\n\n"); int n, fd; char response[] = "ok"; sem_t *sem_match = new sem_t(); // create a new semaphore in heap queue<string> *imgQueue = 0; // queue storing the file names // Init semaphore and put the address of semaphore into map if (sem_init(sem_match, 0, 0) != 0) { errorSocket("ERROR semaphore init failed", sock); } // grap the lock pthread_mutex_lock(&sem_map_lock); sem_map[userID] = sem_match; pthread_mutex_unlock(&sem_map_lock); // reponse to the client if (!orbit) { n = write(sock, response, sizeof(response)); if (n < 0) { error("ERROR writting to socket"); } } else { MsgD.send(sock, response, sizeof(response)); } struct sockaddr_in myaddr; int ret; char buf[1024]; int serverPort = 9879; if (storm) { if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) printf("socket create failed\n"); if (debug) printf("socket created\n"); /* bind it to all local addresses and pick any port number */ memset((char *)&myaddr, 0, sizeof(myaddr)); myaddr.sin_family = AF_INET; myaddr.sin_addr.s_addr = htonl(INADDR_ANY); myaddr.sin_port = htons(serverPort); if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) { perror("bind failed"); goto stop; } if (debug) printf("socket binded\n"); } while(!global_stop) { sem_wait(sem_match); // get the address of image queue if (imgQueue == 0) { imgQueue = queue_map[userID]; } // check if the queue is empty if (imgQueue->empty()) { sem_map.erase(userID); queue_map.erase(userID); user_map.erase(userID); delete(sem_match); delete(imgQueue); sem_destroy(sem_match); // if (orbit) // { // MsgD.close(sock, 0); // } printf("[server] client disconnected --- result\n"); // pthread_exit(NULL); //terminate calling thread! return; } if (!storm) { if (debug) printf("\n----------- start matching -------------\n"); string file_name = imgQueue->front(); if (debug) printf("file name: [%s]\n", file_name.c_str()); imgQueue->pop(); // create a new thread to do the image processing pthread_t thread_id; struct arg_result trans_info; trans_info.sock = sock; strcpy(trans_info.file_name, file_name.c_str()); /* create thread and pass socket and file name to send file */ if (pthread_create(&thread_id, 0, result_child, (void *)&(trans_info)) == -1) { fprintf(stderr,"pthread_create error!\n"); break; //break while loop } pthread_detach(thread_id); } else { // receive part bzero(buf, sizeof(buf)); printf("wait for the result...\n"); ret = recv(fd, buf, sizeof(buf), 0); if (ret < 0) { printf("receive error\n"); } else { int matchedIndex = atoi(buf); printf("received result: %d\n\n", matchedIndex); char defMsg[] = "none"; char sendInfo[200]; if (matchedIndex == 0) { // write none to client if (!orbit) { if (write(sock, defMsg, sizeof(defMsg)) < 0) { errorSocket("ERROR writting to socket", sock); } } else { MsgD.send(sock, defMsg, sizeof(defMsg)); } if (debug) printf("not match\n"); } else { // send result to client string info = ImgMatch::getInfo(matchedIndex); sprintf(sendInfo, "%s,0,0,0,0,0,0,0,0,", info.c_str()); if (debug) printf("sendInfo: %s\n", sendInfo); if (!orbit) { if (write(sock, sendInfo, sizeof(sendInfo)) < 0) { errorSocket("ERROR writting to socket", sock); } } else { MsgD.send(sock, sendInfo, sizeof(sendInfo)); } if (debug) printf("matched image index: %d\n", matchedIndex); } } } // end } stop: if (!orbit) { close(sock); } if (storm) { close(fd); } printf("[server] Connection closed. --- result\n\n"); delete(sem_match); // pthread_exit(NULL); //terminate calling thread! return; }
/****************************************************************************** Description.: this is the transmit child thread it is responsible to send out one frame Input Value.: Return Value: ******************************************************************************/ void *result_child(void *arg) { if (debug) printf("result child thread\n"); struct arg_result *args = (struct arg_result *)arg; int sock = args->sock; char *file_name = args->file_name; int matchedIndex; char defMsg[] = "none"; char sendInfo[200]; vector<float> coord; ImgMatch imgM; // start matching the image imgM.matchImg(file_name); matchedIndex = imgM.getMatchedImgIndex(); if (matchedIndex == 0) { // write none to client if (!orbit) { if (write(sock, defMsg, sizeof(defMsg)) < 0) { errorSocket("ERROR writting to socket", sock); } printf("Not match.\n\n"); } else { MsgD.send(sock, defMsg, sizeof(defMsg)); printf("Not match.\n\n"); } // if (debug) printf("not match\n"); } else { // send result to client coord = imgM.calLocation(); string info = imgM.getInfo(); sprintf(sendInfo, "%s,%f,%f,%f,%f,%f,%f,%f,%f", info.c_str(), coord.at(0), coord.at(1), coord.at(2), coord.at(3), coord.at(4), coord.at(5), coord.at(6), coord.at(7)); printf("Matched Index: %d\n\n", matchedIndex); if (debug) printf("sendInfo: %s\n", sendInfo); if (!orbit) { if (write(sock, sendInfo, sizeof(sendInfo)) < 0) { errorSocket("ERROR writting to socket", sock); } } else { MsgD.send(sock, sendInfo, sizeof(sendInfo)); } // if (debug) printf("matched image index: %d\n", matchedIndex); } if (debug) printf("------------- end matching -------------\n"); return NULL; }
int main(int argc, char *argv[]) { int src_GUID = -1, dst_GUID = -1; /* parameter parsing */ while(1) { int option_index = 0, c = 0; static struct option long_options[] = { {"h", no_argument, 0, 0}, {"help", no_argument, 0, 0}, {"v", no_argument, 0, 0}, {"version", no_argument, 0, 0}, {"orbit", no_argument, 0, 0}, {"d", no_argument, 0, 0}, {"m", required_argument, 0, 0}, {"o", required_argument, 0, 0}, {"storm", no_argument, 0, 0}, {"train", no_argument, 0, 0}, {0, 0, 0, 0} }; c = getopt_long_only(argc, argv, "", long_options, &option_index); /* no more options to parse */ if(c == -1) break; /* unrecognized option */ if(c == '?') { help(); return 0; } switch(option_index) { /* h, help */ case 0: case 1: help(); return 0; break; /* v, version */ case 2: case 3: printf("Real-Time CPS Server Version: 0.1\n" \ "Compilation Date.....: unknown\n" \ "Compilation Time.....: unknown\n"); return 0; break; /* orbit, run in orbit mode */ case 4: orbit = 1; break; /* debug mode */ case 5: debug = 1; break; /* mine GUID */ case 6: src_GUID = strtol(optarg, NULL, 10); break; /* other's GUID */ case 7: dst_GUID = strtol(optarg, NULL, 10); break; /* storm mode */ case 8: storm = 1; break; /* train mode */ case 9: train = 1; break; default: help(); return 0; } } if (!orbit) { /* register signal handler for <CTRL>+C in order to clean up */ if(signal(SIGINT, signal_handler) == SIG_ERR) { printf("could not register signal handler\n"); exit(EXIT_FAILURE); } } // init the mutex lock if (pthread_mutex_init(&user_map_lock, NULL) != 0 || pthread_mutex_init(&queue_map_lock, NULL) != 0 || pthread_mutex_init(&sem_map_lock, NULL) != 0) { printf("\n mutex init failed\n"); return 1; } if (orbit) { if (src_GUID != -1 && dst_GUID != -1) { if (debug) printf("src_GUID: %d, dst_GUID: %d\n", src_GUID, dst_GUID); /* init new Message Distributor */ MsgD.init(src_GUID, dst_GUID, debug); } else { printf("ERROR: please enter src_GUID and dst_GUID with flags -m & -o\n"); exit(1); } } if (train) { // now train with the database ImgMatch::init_DB(100,"/demo/img/","./indexImgTable","ImgIndex.yml"); return 0; } server_run(); return 0; }
/****************************************************************************** Description.: calling this function creates and starts the server threads Input Value.: - Return Value: - ******************************************************************************/ void server_main() { printf("\n[server] start supporting service\n"); if (!orbit) { // init part int sockfd, newsockfd, portno; socklen_t clilen; struct sockaddr_in serv_addr, cli_addr; clilen = sizeof(cli_addr); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { error("ERROR opening socket"); } else if (debug) printf ("[server] obtain socket descriptor successfully.\n"); bzero((char *) &serv_addr, sizeof(serv_addr)); // set up the port number portno = PORT_NO; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { error("ERROR on binding"); } else if (debug) printf("[server] bind tcp port %d sucessfully.\n",portno); if(listen(sockfd,5)) { error("ERROR listening"); } else if (debug) printf ("[server] listening the port %d sucessfully.\n\n", portno); // init finished, now wait for a client while (!global_stop) { pthread_t thread_id; //Block here. Until server accpets a new connection. newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) { // error("ERROR on accept"); fprintf(stderr,"Accept error!\n"); continue; //ignore current socket ,continue while loop. } else printf ("[server] server has got connect from %s, socket id: %d.\n", (char *)inet_ntoa(cli_addr.sin_addr), newsockfd); /* create thread and pass context to thread function */ if (pthread_create(&thread_id, 0, serverThread, (void *)&(newsockfd)) == -1) { fprintf(stderr,"pthread_create error!\n"); break; //break while loop } pthread_detach(thread_id); usleep(1000 * 5); // sleep 5ms to avoid clients gain same sock } /* end of while */ close(sockfd); } // below is orbit mode else { int newsockfd; // init finished, now wait for a client while (!global_stop) { pthread_t thread_id; //Block here. Until server accpets a new connection. newsockfd = MsgD.accept(); if (newsockfd < 0) { // error("ERROR on accept"); fprintf(stderr,"Accept error!\n"); continue; //ignore current socket ,continue while loop. } else printf ("[server] server has got new connection, socket id: %d.\n", newsockfd); /* create thread and pass context to thread function */ if (pthread_create(&thread_id, 0, serverThread, (void *)&(newsockfd)) == -1) { fprintf(stderr,"pthread_create error!\n"); break; //break while loop } pthread_detach(thread_id); usleep(1000 * 5); // sleep 5ms to avoid clients gain same sock } /* end of while */ if (debug) printf("main end\n"); } }
/****************************************************************************** Description: function for transmitting the frames Input Value.: Return Value: ******************************************************************************/ void server_transmit (int sock, string userID) { // printf("transmitting part\n"); int n; char buffer[BUFFER_SIZE]; char response[] = "ok"; char file_name_temp[60]; char *file_name; int write_length = 0; int length = 0; char *block_count_char; int block_count; int count = 0; queue<string> *imgQueue = new queue<string>(); // queue storing the file names // grap the lock pthread_mutex_lock(&queue_map_lock); queue_map[userID] = imgQueue; // put the address of queue into map pthread_mutex_unlock(&queue_map_lock); pthread_mutex_t queueLock; // mutex lock for queue operation sem_t *sem_match = 0; // init the mutex lock if (pthread_mutex_init(&queueLock, NULL) != 0) { errorSocket("ERROR mutex init failed", sock); } if (!orbit) { // reponse to the client n = write(sock, response, sizeof(response)); if (n < 0) { pthread_mutex_destroy(&queueLock); errorSocket("ERROR writting to socket", sock); } while (!global_stop) { // receive the file info bzero(buffer,BUFFER_SIZE); n = read(sock,buffer, sizeof(buffer)); if (n <= 0) { pthread_mutex_destroy(&queueLock); // signal the result thread to terminate sem_post(sem_match); errorSocket("ERROR reading from socket", sock); } // store the file name and the block count file_name = strtok(buffer, ","); strcpy(file_name_temp, file_name); printf("\n[server] file name: %s\n", file_name); block_count_char = strtok(NULL, ","); block_count = strtol(block_count_char, NULL, 10); // printf("block count: %d\n", block_count); // reponse to the client n = write(sock, response, sizeof(response)); if (n <= 0) { pthread_mutex_destroy(&queueLock); // signal the result thread to terminate sem_post(sem_match); errorSocket("ERROR writting to socket", sock); } FILE *fp = fopen(file_name, "w"); if (fp == NULL) { printf("File:\t%s Can Not Open To Write!\n", file_name); break; } // receive the data from server and store them into buffer bzero(buffer, sizeof(buffer)); count = 0; while((length = recv(sock, buffer, BUFFER_SIZE, 0))) { if (length < 0) { printf("Recieve Data From Client Failed!\n"); break; } write_length = fwrite(buffer, sizeof(char), length, fp); if (write_length < length) { printf("File:\t Write Failed!\n"); break; } bzero(buffer, BUFFER_SIZE); ++count; if (count >= block_count) { // printf("block count full\n"); break; } } printf("[server] Recieve Finished!\n\n"); // finished fclose(fp); // lock the queue, ensure there is only one thread modifying the queue pthread_mutex_lock(&queueLock); // store the file name to the waiting queue string file_name_string(file_name_temp); imgQueue->push(file_name_string); pthread_mutex_unlock(&queueLock); // get the address of sem_match if (sem_match == 0) { while (sem_map.find(userID) == sem_map.end()); sem_match = sem_map[userID]; } // signal the result thread to do image processing sem_post(sem_match); } close(sock); } // below is orbit mode else { // get the id length int id_length = 1; int divisor = 10; while (sock / divisor > 0) { ++id_length; divisor *= 10; } int recv_length = BUFFER_SIZE - 6 - id_length; char *file_size_char; int file_size; int received_size = 0; if (debug) printf("\nstart receiving file\n"); // reponse to the client MsgD.send(sock, response, BUFFER_SIZE); while (!global_stop) { received_size = 0; bzero(buffer, BUFFER_SIZE); // get the file info from client n = MsgD.recv(sock, buffer, BUFFER_SIZE); if (n < 0) { errorSocket("ERROR reading from socket", sock); } file_name = strtok(buffer, ","); strcpy(file_name_temp, file_name); printf("\n[server] file name: %s\n", file_name); file_size_char = strtok(NULL, ","); file_size = strtol(file_size_char, NULL, 10); printf("file size: %d\n", file_size); // reponse to the client MsgD.send(sock, response, BUFFER_SIZE); FILE *fp = fopen(file_name, "w"); if (fp == NULL) { printf("File:\t%s Can Not Open To Write!\n", file_name); } // receive the data from server and store them into buffer while(1) { bzero(buffer, BUFFER_SIZE); n = MsgD.recv(sock, buffer, BUFFER_SIZE); if (n < 0) { errorSocket("ERROR reading from socket", sock); } if (file_size - received_size <= recv_length) { int remain = file_size - received_size; write_length = fwrite(buffer, sizeof(char), remain, fp); if (write_length < remain) { printf("File:\t Write Failed!\n"); break; } break; } write_length = fwrite(buffer, sizeof(char), recv_length, fp); if (write_length < recv_length) { printf("File:\t Write Failed!\n"); break; } received_size += BUFFER_SIZE - 6 - id_length; } printf("[server] Recieve Finished!\n\n"); // finished fclose(fp); // lock the queue, ensure there is only one thread modifying the queue pthread_mutex_lock(&queueLock); // store the file name to the waiting queue string file_name_string(file_name_temp); imgQueue->push(file_name_string); pthread_mutex_unlock(&queueLock); // get the address of sem_match if (sem_match == 0) { while (sem_map.find(userID) == sem_map.end()); sem_match = sem_map[userID]; } // signal the result thread to do image processing sem_post(sem_match); } } delete(imgQueue); printf("[server] Connection closed. --- transmit\n\n"); pthread_exit(NULL); //terminate calling thread! }
/****************************************************************************** Description: function for sending back the result Input Value.: Return Value: ******************************************************************************/ void server_result (int sock, string userID) { // printf("result thread\n\n"); int n; char response[BUFFER_SIZE] = "ok"; char defMsg[BUFFER_SIZE] = "none"; int matchedIndex; char sendInfo[BUFFER_SIZE]; vector<float> coord; sem_t *sem_match = new sem_t(); // create a new semaphore in heap queue<string> *imgQueue = 0; // queue storing the file names // Init semaphore and put the address of semaphore into map if (sem_init(sem_match, 0, 0) != 0) { errorSocket("ERROR semaphore init failed", sock); } // grap the lock pthread_mutex_lock(&sem_map_lock); sem_map[userID] = sem_match; pthread_mutex_unlock(&sem_map_lock); // reponse to the client if (!orbit) { n = write(sock, response, sizeof(response)); if (n < 0) { error("ERROR writting to socket"); } } else { MsgD.send(sock, response, BUFFER_SIZE); } while(!global_stop) { sem_wait(sem_match); // get the address of image queue if (imgQueue == 0) { imgQueue = queue_map[userID]; } // check if the queue is empty if (imgQueue->empty()) { sem_map.erase(userID); queue_map.erase(userID); user_map.erase(userID); delete(sem_match); delete(imgQueue); sem_destroy(sem_match); MsgD.close(sock, 0); printf("[server] client disconnectted\n"); pthread_exit(NULL); //terminate calling thread! } if (debug) printf("\n----------- start matching -------------\n"); string file_name = imgQueue->front(); if (debug) printf("file name: %s\n", file_name.c_str()); imgQueue->pop(); // start matching the image imgM.matchImg(file_name); matchedIndex = imgM.getMatchedImgIndex(); if (matchedIndex == 0) { // write none to client if (!orbit) { if (write(sock, defMsg, sizeof(defMsg)) < 0) { errorSocket("ERROR writting to socket", sock); } } else { MsgD.send(sock, defMsg, BUFFER_SIZE); } if (debug) printf("not match\n"); } else { // write index to client coord = imgM.calLocation(); sprintf(sendInfo, "%d,%f,%f,%f,%f,%f,%f,%f,%f", matchedIndex, coord.at(0), coord.at(1), coord.at(2), coord.at(3), coord.at(4), coord.at(5), coord.at(6), coord.at(7)); if (debug) printf("sendInfo: %s\n", sendInfo); if (!orbit) { if (write(sock, sendInfo, sizeof(sendInfo)) < 0) { errorSocket("ERROR writting to socket", sock); } } else { MsgD.send(sock, sendInfo, BUFFER_SIZE); } if (debug) printf("matched image index: %d\n", matchedIndex); } if (debug) printf("------------- end matching -------------\n"); } if (!orbit) { close(sock); } printf("[server] Connection closed. --- result\n\n"); delete(sem_match); pthread_exit(NULL); //terminate calling thread! }