EternalHaru

Untitled

May 28th, 2018
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.15 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pthread.h>
  4. #include <queue>
  5. #include <sys/types.h>
  6. #include <sys/socket.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include <errno.h>
  10. #include <time.h>
  11. #include <string.h>
  12. #include <unordered_map>
  13. #include <sys/un.h>
  14. #include <arpa/inet.h>
  15. #include <fcntl.h>
  16.  
  17. using namespace std;
  18.  
  19. struct server_data;
  20.  
  21. bool flag;
  22. int socket_for_server;//socket_id -> socket_for_server
  23. sockaddr_in address; //self_addr -> address
  24. timespec tm;
  25. unordered_map <int, server_data*> client_map;
  26.  
  27.  
  28. struct server_data {
  29.     int client_id;
  30.     struct sockaddr_in address; //client_addr -> address
  31.     char str_address[INET_ADDRSTRLEN]; // str_addr -> str_address
  32.     queue< pair<char*, int> > q_process, q_send;
  33.     bool flag;
  34.     pthread_t thread_main, thread_reception, thread_process, thread_send;
  35.     pthread_mutex_t mutex_q_process, mutex_q_send;
  36. };
  37.  
  38. void *data_reception(void *args) { //функция приема данных из сокета; func_recv -> data_reception
  39.     server_data *data = (server_data*)args;
  40.     int bytes_read;
  41.     printf("Reception thread started \n");
  42.     fflush(stdout);
  43.     while (data->flag) {
  44.         char *buffer = (char*)malloc(64);
  45.         while ((bytes_read = recv(data->client_id, buffer, 64, 0)) <= 0) {
  46.             if (bytes_read == 0) {
  47.                 data->flag = false;
  48.                 pthread_exit(NULL);
  49.             }
  50.             if (!data->flag) {  
  51.                 pthread_exit(NULL);
  52.             }
  53.             nanosleep(&tm, NULL);
  54.         }
  55.         pthread_mutex_lock(&(data->mutex_q_process));
  56.         data->q_process.push(make_pair(buffer, bytes_read));
  57.         pthread_mutex_unlock(&(data->mutex_q_process));
  58.         printf("Client address:%s Received data: %s\n", data->str_address, buffer);
  59.         fflush(stdout);
  60.     }
  61. }
  62.  
  63. void *data_process(void *args) {
  64.     server_data *data = (server_data*)args;
  65.     pair<char*, int> msg_pair;
  66.     printf("Process thread started\n");
  67.     fflush(stdout);
  68.     while (data->flag) {
  69.         while (true) {
  70.             pthread_mutex_lock(&(data->mutex_q_process));
  71.             if (!data->q_process.empty()) {
  72.                 pthread_mutex_unlock(&(data->mutex_q_process));
  73.                 break;
  74.             }            
  75.             pthread_mutex_unlock(&(data->mutex_q_process));
  76.             if (!data->flag) {
  77.                 pthread_exit(NULL);
  78.             }
  79.             nanosleep(&tm, NULL);
  80.         }
  81.         pthread_mutex_lock (&(data->mutex_q_process));
  82.         msg_pair = data->q_process.front();
  83.         data->q_process.pop();
  84.         pthread_mutex_unlock(&(data->mutex_q_process));
  85.         const time_t timer = time(NULL);
  86.         char *new_buffer = (char*)malloc(64);
  87.         sprintf(new_buffer, "(Send: %s Date: %s\n)", msg_pair.first, ctime(&timer));
  88.         msg_pair.second = strlen(new_buffer);
  89.         free(msg_pair.first);
  90.         msg_pair.first = new_buffer;
  91.  
  92.         pthread_mutex_lock(&(data->mutex_q_send));
  93.         data->q_send.push(msg_pair);
  94.         pthread_mutex_unlock(&(data->mutex_q_send));
  95.  
  96.         printf("Client address:%s Send to client: %s\n", data->str_address, new_buffer);
  97.        
  98.         fflush(stdout);
  99.     }
  100.     printf("Process thread ended\n");
  101. }
  102.  
  103. void *data_send(void *args) {
  104.     server_data *data = (server_data*)args;
  105.     pair <char*, int> msg_pair;
  106.     int bytes_send;
  107.     printf("Sending thread started\n");
  108.     fflush(stdout);
  109.     while (data->flag) {
  110.         while (true) {
  111.             pthread_mutex_lock(&(data->mutex_q_send));
  112.             if (!data->q_send.empty()) {
  113.                 pthread_mutex_unlock(&(data->mutex_q_send));
  114.                 break;
  115.             }
  116.             pthread_mutex_unlock(&(data->mutex_q_send));
  117.             if (!data->flag) {
  118.                 printf("Sending thread close\n");
  119.                 pthread_exit(NULL);
  120.             }
  121.             nanosleep(&tm, NULL);
  122.         }
  123.         pthread_mutex_lock(&(data->mutex_q_send));
  124.         msg_pair = data->q_send.front();
  125.         data->q_send.pop();
  126.         pthread_mutex_unlock(&(data->mutex_q_send));
  127.         bytes_send = send(data->client_id, msg_pair.first, msg_pair.second, 0);
  128.        
  129.         if (bytes_send <= 0) {
  130.             data->flag = false;
  131.             pthread_exit(NULL);
  132.         }
  133.  
  134.         fflush(stdout);
  135.     }
  136.     printf("Sending thread close");
  137. }
  138.  
  139. void *func_create_client_thread(void *args) {
  140.     server_data *data = (server_data*)args;
  141.  
  142.     inet_ntop(AF_INET, &(data->address.sin_addr), data->str_address, INET_ADDRSTRLEN);
  143.     data->flag = true;
  144.     client_map[data->client_id] = data;
  145.  
  146.     printf("Client thread started\n");
  147.  
  148.     pthread_mutex_init(&(data->mutex_q_process), NULL);
  149.     pthread_mutex_init(&(data->mutex_q_send), NULL);
  150.  
  151.     pthread_create(&(data->thread_reception), NULL, &data_reception, (void*)data);
  152.     pthread_create(&(data->thread_process), NULL, &data_process, (void*)data);
  153.     pthread_create(&(data->thread_send), NULL, &data_send, (void*)data);
  154.  
  155.     pthread_join(data->thread_reception, NULL);
  156.     pthread_join(data->thread_process, NULL);
  157.     pthread_join(data->thread_send, NULL);
  158.  
  159.     pthread_mutex_destroy(&(data->mutex_q_process));
  160.     pthread_mutex_destroy(&(data->mutex_q_send));
  161.  
  162.     shutdown(data->client_id, SHUT_WR);
  163.     close(data->client_id);
  164.  
  165.     printf("Client thread close\n");
  166. }
  167.            
  168. void *data_listen(void *args) {
  169.     printf("Listen thread started\n");
  170.     int client_addr_sz = sizeof(struct sockaddr_in);
  171.     while (flag) {
  172.         server_data *data = new server_data;
  173.         while ((data->client_id = accept(socket_for_server, (sockaddr*)&(data->address), (socklen_t*)&client_addr_sz)) == -1) {
  174.             if (!flag) {
  175.                 printf("Listen thread close\n");
  176.                 pthread_exit(NULL);
  177.             }
  178.             nanosleep(&tm, NULL);
  179.         }
  180.         int flags = fcntl(data->client_id, F_GETFL);
  181.         fcntl(data->client_id, F_SETFL, flags | O_NONBLOCK);
  182.  
  183.         pthread_create(&(data->thread_main), NULL, &func_create_client_thread, (void*)data);
  184.     }
  185.     printf("Listen thread close\n");
  186. }
  187.  
  188. int main()
  189. {
  190.     flag = true;
  191.     tm.tv_sec = 0;
  192.     tm.tv_nsec = 10000000;
  193.  
  194.     address.sin_family = AF_INET;
  195.     address.sin_port = htons(31337);
  196.     address.sin_addr.s_addr = htonl(INADDR_ANY);
  197.     socket_for_server = socket(AF_INET, SOCK_STREAM, 0);
  198.     int flags = fcntl(socket_for_server, F_GETFL);
  199.     fcntl(socket_for_server, F_SETFL, flags | O_NONBLOCK);
  200.  
  201.     int yes = 1;
  202.     setsockopt(socket_for_server, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
  203.     int res = bind(socket_for_server, (struct sockaddr *)&address, sizeof(struct sockaddr));
  204.     res = listen(socket_for_server, 10);
  205.     pthread_t thread_listen; //thr_listen -> thread_listen
  206.     pthread_create(&thread_listen, NULL, &data_listen, NULL);
  207.     getchar();
  208.     flag = false;
  209.     pthread_join(thread_listen, NULL);
  210.     for( const auto &t_data : client_map ) {
  211.         t_data.second->flag = false;
  212.         pthread_join(t_data.second->thread_main, NULL);
  213.     }
  214.     shutdown(socket_for_server, SHUT_RDWR);
  215.     close(socket_for_server);
  216.     printf("Server shut down\n");
  217.     return 0;
  218. }
Advertisement
Add Comment
Please, Sign In to add comment