Advertisement
Guest User

Untitled

a guest
Sep 23rd, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.25 KB | None | 0 0
  1. /*
  2.   This application listeners for socket connections, data sent to the socket will be reversed and
  3.   sent back to the sender of the data, the socket connection will be closed
  4.  */
  5.  
  6. #include <unistd.h>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10.  
  11. #include <pthread.h>
  12. #include <sys/socket.h>
  13. #include <sys/un.h>
  14. #include <sys/types.h>
  15.  
  16. #define MAX_CLIENTS 10
  17. #define BUFFER_SIZE 8192
  18.  
  19. // Prototypes
  20. void * handle_client_sock(void * arg);
  21. char * strrev(const char * data, size_t len);
  22.  
  23. // Constants
  24. const char * socket_file = "/tmp/reverser.sock";
  25.  
  26. // Global variables
  27. static int next_idx = 0;
  28. static int client_sockfds[MAX_CLIENTS];
  29. static struct sockaddr_un client_addresses[MAX_CLIENTS];
  30.  
  31. int main()
  32. {
  33.     int res;
  34.     int serv_sockfd;
  35.     int server_len;
  36.     socklen_t client_len;
  37.     struct sockaddr_un server_address;
  38.     pthread_t cli_threads[MAX_CLIENTS];
  39.     pthread_attr_t thread_attr;
  40.  
  41.     unlink(socket_file);
  42.     serv_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
  43.     server_address.sun_family = AF_UNIX;
  44.     strcpy(server_address.sun_path, socket_file);
  45.     server_len = sizeof(server_address);
  46.     bind(serv_sockfd, (struct sockaddr *) &server_address, server_len);
  47.  
  48.     // Initialize detached thread attributes
  49.     res = pthread_attr_init(&thread_attr);
  50.     if (res) {
  51.         perror("Attributes");
  52.         return 1;
  53.     }
  54.  
  55.     res = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
  56.     if (res) {
  57.         perror("detached attr set");
  58.         return 1;
  59.     }
  60.    
  61.     listen(serv_sockfd, 5);
  62.     for (;;) {
  63.         int id_to_pass = next_idx;
  64.         puts("Server waiting...");
  65.  
  66.         if (id_to_pass >= MAX_CLIENTS) {
  67.             puts("Max threads reached");           
  68.             break;
  69.         }
  70.  
  71.         client_len = sizeof(client_addresses[0]);
  72.         client_sockfds[id_to_pass] = accept(serv_sockfd,
  73.                           (struct sockaddr *) &client_addresses[id_to_pass],
  74.                           &client_len);
  75.  
  76.         if (client_sockfds[id_to_pass] == -1) {
  77.             puts("invalid fd");
  78.             continue;
  79.         }
  80.        
  81.         pthread_create(&cli_threads[id_to_pass], &thread_attr, handle_client_sock, (void * ) &id_to_pass);
  82.         ++next_idx;
  83.     }
  84.  
  85.     pthread_attr_destroy(&thread_attr);
  86.  
  87.     // First wait for threads ..
  88.     for (;;) {
  89.         puts("Waiting for threads to stop");
  90.        
  91.         if (! next_idx) break;
  92.         sleep(5);
  93.     }
  94.    
  95.     close(serv_sockfd);
  96.     unlink(socket_file);
  97.    
  98.     return 0;
  99. }
  100.  
  101. void * handle_client_sock(void * arg)
  102. {
  103.     // Handle the socket
  104.     char buffer[BUFFER_SIZE];
  105.     int sock_id = *(int *) arg;
  106.     size_t b_read;
  107.  
  108.     printf("Thread num %d\n", sock_id);
  109.     printf("Handling socket id: %d\n", client_sockfds[sock_id]);
  110.  
  111.     // Read some data from the socket
  112.     b_read = read(client_sockfds[sock_id], buffer, BUFFER_SIZE);
  113.     printf("Bytes read: %d\n", (int) b_read);
  114.  
  115.     // Reverse the string
  116.     char * reversed = strrev(buffer, b_read);
  117.     printf("Reversed: %s\n", reversed);
  118.     write(client_sockfds[sock_id], reversed, b_read);
  119.    
  120.     close(client_sockfds[sock_id]);
  121.  
  122.     // Lower the next, if not equal to zero
  123.         --next_idx;
  124.  
  125.     // Free resources
  126.     free(reversed);
  127.  
  128.     // Exit succesfully
  129.     puts("Stopping thread");
  130.     pthread_exit(0);
  131. }
  132.  
  133. char * strrev(const char * data, size_t len)
  134. {
  135.     char * dest = (char*) malloc(len + 1);
  136.     const char * last = data + (len - 1);
  137.  
  138.     for (char * dptr = dest; last >= data; ++dptr, --last)
  139.         *dptr = *last;
  140.  
  141.     *(dest + len) = '\0';
  142.  
  143.     return dest;
  144. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement