Advertisement
Guest User

Untitled

a guest
Apr 26th, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.19 KB | None | 0 0
  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <netdb.h>
  4. #include <netinet/in.h>
  5. #include <arpa/inet.h>
  6. #include <unistd.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <limits.h>
  11. #include <signal.h>
  12. #include <sys/wait.h>
  13.  
  14. int counter = 1;
  15. volatile int flag = 0;
  16. int arr[1000000];
  17. int arrsize = 0;
  18.  
  19. // должен закрывать все открытые дескрипторы
  20. void handler(int s) {
  21.     for (int i = 0; i < arrsize; ++i) {
  22.         kill(arr[i], SIGTERM);
  23.     }
  24.     while (wait(NULL) > 0);
  25.     exit(0);
  26. }
  27.  
  28. int main(int argc, char *argv[]) {
  29.     struct sigaction sa = {};
  30.     sa.sa_flags = SA_RESTART;
  31.     sa.sa_handler = handler;
  32.     sigaction(SIGTERM, &sa, NULL);
  33.  
  34.     int fd = socket(PF_INET, SOCK_STREAM, 0);
  35.     if (fd < 0) {
  36.         perror("socket");
  37.         return 1;
  38.     }
  39.  
  40.     int val = 1;
  41.     setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
  42.     setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
  43.  
  44.     struct sockaddr_in s1;
  45.     s1.sin_family = AF_INET;
  46.     s1.sin_port = htons(strtol(argv[1], NULL, 10));
  47.     s1.sin_addr.s_addr = INADDR_ANY;
  48.     int r = bind(fd, (struct sockaddr*) &s1, sizeof(struct sockaddr_in));
  49.     if (r < 0) {
  50.         perror("bind");
  51.         return 1;
  52.     }
  53.  
  54.     listen(fd, 5);
  55.  
  56.     ssize_t res;
  57.     char buf[1024];
  58.  
  59.     while (1) {
  60.         while (waitpid(-1, NULL, WNOHANG) > 0);
  61.        
  62.         struct sockaddr_in s2;
  63.         socklen_t slen = sizeof(s2);
  64.         int fd2 = accept(fd, (struct sockaddr*) &s2, &slen);
  65.  
  66.         // для каждого клиента создаем отдельный процесс
  67.         if (!fork()) {
  68.             arr[arrsize] = getpid();
  69.             arrsize++;
  70.  
  71.             close(fd);
  72.             int myNum = counter++;
  73.  
  74.             sprintf(buf, "%s\r\n", argv[2]);
  75.             res = write(fd2, buf, strlen(buf));
  76.             if (res <= 0) {
  77.                 exit(0);
  78.             }
  79.             sprintf(buf, "%d\r\n", myNum);
  80.             res = write(fd2, buf, strlen(buf));
  81.             if (res <= 0) {
  82.                 exit(0);
  83.             }
  84.  
  85.             int maxNum;
  86.  
  87.             res = read(fd2, buf, sizeof(buf));
  88.             if (res <= 0) {
  89.                 exit(0);
  90.             }
  91.             buf[res] = '\0';
  92.             maxNum = strtol(buf, NULL, 10);
  93.  
  94.             while (1) {
  95.                 res = read(fd2, buf, sizeof(buf));
  96.                 if (res <= 0) {
  97.                     exit(0);
  98.                 }
  99.                 buf[res] = '\0';
  100.  
  101.                 int num = strtol(buf, NULL, 10);
  102.                 if (num > maxNum || num > INT_MAX - myNum) {
  103.                     strcpy(buf, "-1\r\n");
  104.                     res = write(fd2, buf, 4);
  105.                     if (res <= 0) {
  106.                         exit(0);
  107.                     }
  108.                     close(fd2);
  109.                     return 0;
  110.                 } else {
  111.                     sprintf(buf, "%d\r\n", num + myNum);
  112.                     res = write(fd2, buf, strlen(buf));
  113.                     if (res <= 0) {
  114.                         exit(0);
  115.                     }
  116.                 }
  117.             }
  118.         }
  119.         close(fd2);
  120.     }
  121.     exit(0);
  122. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement