Advertisement
tftrgi11

client

Jun 20th, 2020
1,413
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.56 KB | None | 0 0
  1. #include <stdbool.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6.  
  7. #include <errno.h>
  8. #include <getopt.h>
  9. #include <netdb.h>
  10. #include <netinet/in.h>
  11. #include <netinet/ip.h>
  12. #include <sys/socket.h>
  13. #include <sys/types.h>
  14.  
  15. struct Server {
  16.   char ip[255];
  17.   int port;
  18. };
  19.  
  20. uint64_t MultModulo(uint64_t a, uint64_t b, uint64_t mod) {
  21.   uint64_t result = 0;
  22.   a = a % mod;
  23.   while (b > 0) {
  24.     if (b % 2 == 1)
  25.       result = (result + a) % mod;
  26.     a = (a * 2) % mod;
  27.     b /= 2;
  28.   }
  29.  
  30.   return result % mod;
  31. }
  32.  
  33. bool ConvertStringToUI64(const char *str, uint64_t *val) {
  34.   char *end = NULL;
  35.   unsigned long long i = strtoull(str, &end, 10);
  36.   if (errno == ERANGE) {
  37.     fprintf(stderr, "Out of uint64_t range: %s\n", str);
  38.     return false;
  39.   }
  40.  
  41.   if (errno != 0)
  42.     return false;
  43.  
  44.   *val = i;
  45.   return true;
  46. }
  47.  
  48. int main(int argc, char **argv) {
  49.   uint64_t k = -1;
  50.   uint64_t mod = -1;
  51.   char servers[255] = {'\0'}; // max filename length = 255
  52.  
  53.  
  54.   while (true) {
  55.     int current_optind = optind ? optind : 1;
  56.  
  57.     static struct option options[] = {{"k", required_argument, 0, 0},
  58.                                       {"mod", required_argument, 0, 0},
  59.                                       {"servers", required_argument, 0, 0},
  60.                                       {0, 0, 0, 0}};
  61.  
  62.     int option_index = 0;
  63.     int c = getopt_long(argc, argv, "", options, &option_index);
  64.  
  65.     if (c == -1)
  66.       break;
  67.  
  68.     switch (c) {
  69.     case 0: {
  70.       switch (option_index) {
  71.       case 0:
  72.         ConvertStringToUI64(optarg, &k);
  73.         if (k < 1)
  74.         {
  75.             printf("k must be positive");
  76.             return 1;
  77.         }
  78.         break;
  79.       case 1:
  80.         ConvertStringToUI64(optarg, &mod);
  81.         if (mod < 1)
  82.         {
  83.             printf("mod must be positive");
  84.             return 1;
  85.         }
  86.         break;
  87.       case 2:
  88.         memcpy(servers, optarg, strlen(optarg));
  89.         break;
  90.       default:
  91.         printf("Index %d is out of options\n", option_index);
  92.       }
  93.     } break;
  94.  
  95.     case '?':
  96.       printf("Arguments error\n");
  97.       break;
  98.     default:
  99.       fprintf(stderr, "getopt returned character code 0%o?\n", c);
  100.     }
  101.   }
  102.  
  103.   if (k == -1 || mod == -1 || !strlen(servers)) {
  104.     fprintf(stderr, "Using: %s --k 1000 --mod 5 --servers /path/to/file\n",
  105.             argv[0]);
  106.     return 1;
  107.   }
  108.  
  109.   FILE *serversFile;
  110.  
  111.   serversFile = fopen(servers, "r");
  112.   if (serversFile == NULL)
  113.   {
  114.       printf("Could not open servers file");
  115.       return 1;
  116.   }
  117.   char buff[255];
  118.   int port;
  119.   unsigned int servers_num = 0;
  120.   while (fscanf(serversFile, "%s %d\n", buff, &port)!=EOF) servers_num++;
  121.   rewind(serversFile);
  122.   struct Server *to = malloc(sizeof(struct Server) * servers_num);
  123.   int count = 0;
  124.   while (fscanf(serversFile, "%s %d\n", buff, &port)!=EOF && count != 20)
  125.   {
  126.       to[count].port = port;
  127.       memcpy(to[count].ip, buff, sizeof(buff));
  128.       count++;
  129.   }
  130.  
  131.  
  132.   uint64_t result = 1;
  133.   int sockets[servers_num];
  134.   for (int i = 0; i < servers_num; i++) {
  135.     struct hostent *hostname = gethostbyname(to[i].ip);
  136.     if (hostname == NULL) {
  137.       fprintf(stderr, "gethostbyname failed with %s\n", to[i].ip);
  138.       exit(1);
  139.     }
  140.  
  141.     struct sockaddr_in server;
  142.     server.sin_family = AF_INET;
  143.     server.sin_port = htons(to[i].port);
  144.     server.sin_addr.s_addr = *((unsigned long *)hostname->h_addr_list[0]);
  145.  
  146.     sockets[i] = socket(AF_INET, SOCK_STREAM, 0);
  147.     if (sockets[i] < 0) {
  148.       fprintf(stderr, "Socket creation failed!\n");
  149.       exit(1);
  150.     }
  151.  
  152.     if (connect(sockets[i], (struct sockaddr *)&server, sizeof(server)) < 0) {
  153.       fprintf(stderr, "Connection failed\n");
  154.       exit(1);
  155.     }
  156.     uint64_t begin = 2 + i*k/servers_num;
  157.     uint64_t end = (i+1)*k/servers_num;
  158.  
  159.     char task[sizeof(uint64_t) * 3];
  160.     memcpy(task, &begin, sizeof(uint64_t));
  161.     memcpy(task + sizeof(uint64_t), &end, sizeof(uint64_t));
  162.     memcpy(task + 2 * sizeof(uint64_t), &mod, sizeof(uint64_t));
  163.  
  164.     if (send(sockets[i], task, sizeof(task), 0) < 0) {
  165.       fprintf(stderr, "Send failed\n");
  166.       exit(1);
  167.     }
  168.   }
  169.  
  170. for (int i = 0; i < servers_num; i++)
  171. {
  172.     char response[sizeof(uint64_t)];
  173.     if (recv(sockets[i], response, sizeof(response), 0) < 0) {
  174.       fprintf(stderr, "Recieve failed\n");
  175.       exit(1);
  176.     }
  177.     uint64_t answer = 0;
  178.     memcpy(&answer, response, sizeof(uint64_t));
  179.     result = (result * answer) % mod;
  180.     close(sockets[i]);
  181. }
  182.  
  183.   printf("answer: %lu\n", result);
  184.   free(to);
  185.  
  186.   return 0;
  187. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement