Telnet chat server for Linux x86_64

Тема в разделе "WASM.BEGINNERS", создана пользователем Hacker, 16 июл 2023.

  1. Hacker

    Hacker Member

    Публикаций:
    0
    Регистрация:
    9 авг 2018
    Сообщения:
    132
    Адрес:
    Москва
    Просто помогите поправь и оптимизировать уже имеющийся код. Может что-то там недописали. Сервер зависает после нескольких сообщений из telnet GNU, а из PuTTY вообще падает
     
  2. alex_dz

    alex_dz Active Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    209
    сколько $ в час плотите
    или сумарно на сколько бюджет
     
  3. Hacker

    Hacker Member

    Публикаций:
    0
    Регистрация:
    9 авг 2018
    Сообщения:
    132
    Адрес:
    Москва
    Код (Text):
    1.  
    2. //Powered by antichat
    3. //telnet chat server
    4. //19.09.2023
    5. //gcc tcs.c -o tcs
    6.  
    7. #include <stdio.h>
    8. #include <stdlib.h>
    9. #include <string.h>
    10. #include <sys/socket.h>
    11. #include <netinet/in.h>
    12. #include <arpa/inet.h>
    13. #include <errno.h>
    14. #include <sys/types.h>
    15. #include <time.h>
    16. #include <unistd.h>
    17. #include <assert.h>
    18. #include <fcntl.h>
    19. #include <poll.h>
    20. #include <sys/ioctl.h>
    21.  
    22. #define FDS_ARRAY_CHUNK_SIZE 100
    23. #define MAX_MESSAGE_LEN 1728
    24. struct pollfd *fds;
    25. int fds_len;
    26.  
    27. void extend_fds()//extending fds array
    28. {
    29.     int i;
    30.  
    31.     fds = realloc(fds, (fds_len + FDS_ARRAY_CHUNK_SIZE) * sizeof(struct pollfd));
    32.    
    33.     for (i = 0; i < FDS_ARRAY_CHUNK_SIZE; i++) {
    34.         fds[fds_len + i].fd = -1;
    35.         fds[fds_len + i].events = 0;
    36.     }
    37.  
    38.     fds_len += FDS_ARRAY_CHUNK_SIZE;
    39.    
    40. }
    41.  
    42. void fds_set(int fd)//add fd to fds
    43. {
    44.     int i;
    45.  
    46.     for (i = 0; ; i++) {
    47.        
    48.         if (i == fds_len) extend_fds();
    49.  
    50.         if (fds[i].fd < 0) {
    51.             fds[i].fd = fd;
    52.             fds[i].events = POLLIN;
    53.             fds[i].revents = 0;
    54.             break;
    55.         }
    56.     }
    57. }
    58.  
    59. void fds_clr(int fd) // remove fd from fds
    60. {
    61.     int i;
    62.  
    63.     for (i = 0; i < fds_len; i++) {
    64.         if (fds[i].fd == fd) {
    65.             fds[i].fd = -1;
    66.                 fds[i].events = 0; 
    67.             break;
    68.         }
    69.     }
    70. }
    71. void set_nonblock(int socket)
    72. {    
    73.     int flags;    
    74.     flags = fcntl(socket,F_GETFL,0);    
    75.     assert(flags != -1);    
    76.     fcntl(socket, F_SETFL, flags | O_NONBLOCK);
    77. }
    78. void send_to_all(int servfd, int fd,  char *buff, int len)
    79. {
    80.     int i;
    81.  
    82.     for (i = 0; i < fds_len; i++) {
    83.         if (fds[i].fd > 0 && fd != fds[i].fd && fds[i].fd != servfd) {
    84.             write(fds[i].fd, buff, len);//TODO check return value and mark fd as closed
    85.            
    86.         }
    87.     }
    88. }
    89.  
    90. int telnet_negotiate_linemode(int fd)
    91. {
    92.     char do_linemode[] = {255, 253, 34};
    93.     char on_linemode[] = {255, 250, 34, 1, 1, 255, 240};
    94.     char will_echo[] = {255, 253, 1};
    95.     char wont_echo[] = {255, 252, 1};
    96.     char reply_buff[512];
    97.     int n;
    98.  
    99.    
    100.  
    101.     write(fd, do_linemode, sizeof(do_linemode));
    102.     write(fd, on_linemode, sizeof(on_linemode));
    103.     write(fd, will_echo, sizeof(will_echo));
    104.     write(fd, wont_echo, sizeof(wont_echo));
    105.  
    106.     read(fd, reply_buff, sizeof(reply_buff));
    107.  
    108.     return 0;
    109.  
    110. }
    111.  
    112. void replace_commands_with_spaces(char *buff, int len)
    113. {
    114.     int i;
    115.     unsigned char c;
    116.  
    117.     for (i = 0; i < len && buff[i] != 0; i++) {
    118.         c = buff[i];
    119.         if (c < ' ' || c > 126) {
    120.             c = ' ';//replacing with spaces
    121.         }  
    122.     }
    123. }
    124. int main(int argc, char** argv)
    125. {
    126.     struct sockaddr_in servaddr;
    127.     int servfd, connfd, port, pollret;
    128.     char *host, buff[MAX_MESSAGE_LEN], cleaned_buff[MAX_MESSAGE_LEN];
    129.     int i, msg_len, on, negresult;
    130.    
    131.     fds = NULL;
    132.     fds_len = 0;
    133.     on  = 1;
    134.  
    135.     setbuf(stdout, NULL);  
    136.    
    137.     if (argc != 3) {
    138.         perror("Please provide host and port. Example: telnet-chat 0.0.0.0 4022\r\n");
    139.         exit(1);
    140.     }  
    141.  
    142.     memset(&servaddr, 0, sizeof(servaddr));
    143.     servfd = socket(AF_INET, SOCK_STREAM, 0);
    144.  
    145.     host = argv[1];
    146.     port = atoi(argv[2]);
    147.  
    148.     servaddr.sin_family = AF_INET;
    149.     servaddr.sin_addr.s_addr = inet_addr(host);
    150.     servaddr.sin_port = htons(port);
    151.  
    152.     bind(servfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
    153.  
    154.     listen(servfd, 1024);
    155.  
    156.     ioctl(servfd, FIONBIO, (char*)&on);
    157.    
    158.     fds_set(servfd);
    159.  
    160.     while(1) {
    161.         pollret = poll(fds, fds_len, 100);
    162.  
    163.         for (i = 0; i < fds_len; i++) {
    164.             if (fds[i].fd > 0) {
    165.                 if (fds[i].revents & POLLIN) {
    166.                     if (fds[i].fd == servfd) {
    167.                         connfd = accept(servfd, (struct sockaddr*)NULL, NULL);
    168.                         telnet_negotiate_linemode(connfd);
    169.                         fds_set(connfd);
    170.                     } else {
    171.                         msg_len = read(fds[i].fd, buff, MAX_MESSAGE_LEN);
    172.                         replace_commands_with_spaces(buff, msg_len);
    173.                         send_to_all(servfd, fds[i].fd, buff, msg_len);
    174.                     }
    175.                 }
    176.                    
    177.                 if(fds[i].revents & POLLHUP ) {            
    178.                     //closed by peer            
    179.                     close(fds[i].fd);
    180.                     fds[i].fd = -1;
    181.                     fds[i].events = 0;
    182.                 }
    183.             }
    184.         }
    185.        
    186.     }
    187.     return 0;
    188.  
    189. }
    190.