Advertisement
tftrgi11

Untitled

Jun 19th, 2020
2,377
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.17 KB | None | 0 0
  1. #include <limits.h>
  2. #include <stdbool.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <unistd.h>
  7.  
  8. #include <getopt.h>
  9. #include <netinet/in.h>
  10. #include <netinet/ip.h>
  11. #include <sys/socket.h>
  12. #include <sys/types.h>
  13.  
  14. #include "pthread.h"
  15.  
  16. struct FactorialArgs {
  17.   uint64_t begin;
  18.   uint64_t end;
  19.   uint64_t mod;
  20. };
  21.  
  22. uint64_t MultModulo(uint64_t a, uint64_t b, uint64_t mod) {
  23.   uint64_t result = 0;
  24.   a = a % mod;
  25.   while (b > 0) {
  26.     if (b % 2 == 1)
  27.       result = (result + a) % mod;
  28.     a = (a * 2) % mod;
  29.     b /= 2;
  30.   }
  31.  
  32.   return result % mod;
  33. }
  34.  
  35. uint64_t Factorial(const struct FactorialArgs *args) {
  36.   uint64_t ans = 1;
  37.   uint64_t begin = args->begin;
  38.   uint64_t end = args->end;
  39.   uint64_t mod = args->mod;
  40.   while (begin <= end)
  41.   {
  42.       if (begin == end)
  43.       {
  44.           ans = (ans*begin)%mod;
  45.           break;
  46.       }
  47.       ans = (ans*begin*end)%mod;
  48.       ++begin;
  49.       --end;
  50.   }
  51.  
  52.   return ans;
  53. }
  54.  
  55. void *ThreadFactorial(void *args) {
  56.   struct FactorialArgs *fargs = (struct FactorialArgs *)args;
  57.   return (void *)(uint64_t *)Factorial(fargs);
  58. }
  59.  
  60. int main(int argc, char **argv) {
  61.   int tnum = -1;
  62.   int port = -1;
  63.  
  64.   while (true) {
  65.     int current_optind = optind ? optind : 1;
  66.  
  67.     static struct option options[] = {{"port", required_argument, 0, 0},
  68.                                       {"tnum", required_argument, 0, 0},
  69.                                       {0, 0, 0, 0}};
  70.  
  71.     int option_index = 0;
  72.     int c = getopt_long(argc, argv, "", options, &option_index);
  73.  
  74.     if (c == -1)
  75.       break;
  76.  
  77.     switch (c) {
  78.     case 0: {
  79.       switch (option_index) {
  80.       case 0:
  81.         port = atoi(optarg);
  82.         if (port < 1024 || port > 49151)
  83.         {
  84.             printf("Invalid port\n");
  85.             return 1;
  86.         }
  87.         break;
  88.       case 1:
  89.         tnum = atoi(optarg);
  90.         if (tnum < 1)
  91.         {
  92.             printf("tnum must be positive");
  93.             return 1;
  94.         }
  95.         break;
  96.       default:
  97.         printf("Index %d is out of options\n", option_index);
  98.       }
  99.     } break;
  100.  
  101.     case '?':
  102.       printf("Unknown argument\n");
  103.       break;
  104.     default:
  105.       fprintf(stderr, "getopt returned character code 0%o?\n", c);
  106.     }
  107.   }
  108.  
  109.   if (port == -1 || tnum == -1) {
  110.     fprintf(stderr, "Using: %s --port 20001 --tnum 4\n", argv[0]);
  111.     return 1;
  112.   }
  113.  
  114.   int server_fd = socket(AF_INET, SOCK_STREAM, 0);
  115.   if (server_fd < 0) {
  116.     fprintf(stderr, "Can not create server socket!");
  117.     return 1;
  118.   }
  119.  
  120.   struct sockaddr_in server;
  121.   server.sin_family = AF_INET;
  122.   server.sin_port = htons((uint16_t)port);
  123.   server.sin_addr.s_addr = htonl(INADDR_ANY);
  124.  
  125.   int opt_val = 1;
  126.   setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val));
  127.  
  128.   int err = bind(server_fd, (struct sockaddr *)&server, sizeof(server));
  129.   if (err < 0) {
  130.     fprintf(stderr, "Can not bind to socket!");
  131.     return 1;
  132.   }
  133.  
  134.   err = listen(server_fd, 128);
  135.   if (err < 0) {
  136.     fprintf(stderr, "Could not listen on socket\n");
  137.     return 1;
  138.   }
  139.  
  140.   printf("Server listening at %d\n", port);
  141.  
  142.   while (true) {
  143.     struct sockaddr_in client;
  144.     socklen_t client_len = sizeof(client);
  145.     int client_fd = accept(server_fd, (struct sockaddr *)&client, &client_len);
  146.  
  147.     if (client_fd < 0) {
  148.       fprintf(stderr, "Could not establish new connection\n");
  149.       continue;
  150.     }
  151.  
  152.     while (true) {
  153.       unsigned int buffer_size = sizeof(uint64_t) * 3;
  154.       char from_client[buffer_size];
  155.       int read = recv(client_fd, from_client, buffer_size, 0);
  156.  
  157.       if (!read)
  158.         break;
  159.       if (read < 0) {
  160.         fprintf(stderr, "Client read failed\n");
  161.         break;
  162.       }
  163.       if (read < buffer_size) {
  164.         fprintf(stderr, "Client send wrong data format\n");
  165.         break;
  166.       }
  167.  
  168.       pthread_t threads[tnum];
  169.  
  170.       uint64_t begin = 0;
  171.       uint64_t end = 0;
  172.       uint64_t mod = 0;
  173.       memcpy(&begin, from_client, sizeof(uint64_t));
  174.       memcpy(&end, from_client + sizeof(uint64_t), sizeof(uint64_t));
  175.       memcpy(&mod, from_client + 2 * sizeof(uint64_t), sizeof(uint64_t));
  176.  
  177.       fprintf(stdout, "Receive: %lu %lu %lu\n", begin, end, mod);
  178.  
  179.       struct FactorialArgs args[tnum];
  180.       for (uint32_t i = 0; i < tnum; i++) {
  181.         args[i].begin = begin + i*(end-begin)/tnum;
  182.         args[i].end = begin + (i+1)*(end-begin)/tnum;
  183.         args[i].mod = mod;
  184.  
  185.         if (pthread_create(&threads[i], NULL, ThreadFactorial,
  186.                            (void *)&args[i])) {
  187.           printf("Error: pthread_create failed!\n");
  188.           return 1;
  189.         }
  190.       }
  191.  
  192.       uint64_t total = 1;
  193.       for (uint32_t i = 0; i < tnum; i++) {
  194.         uint64_t result = 0;
  195.         pthread_join(threads[i], (void **)&result);
  196.         total = (total*result)%mod;
  197.       }
  198.  
  199.       printf("Total: %lu\n", total);
  200.  
  201.       char buffer[sizeof(total)];
  202.       memcpy(buffer, &total, sizeof(total));
  203.       err = send(client_fd, buffer, sizeof(total), 0);
  204.       if (err < 0) {
  205.         fprintf(stderr, "Can't send data to client\n");
  206.         break;
  207.       }
  208.     }
  209.  
  210.     shutdown(client_fd, SHUT_RDWR);
  211.     close(client_fd);
  212.   }
  213.  
  214.   return 0;
  215. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement