Advertisement
Guest User

Untitled

a guest
Oct 17th, 2017
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.31 KB | None | 0 0
  1. #include "stdio.h"
  2. #include "winsock.h"
  3. #include "windows.h"
  4. #include "time.h"
  5. #include "conio.h"
  6.  
  7. #define BUFFER_SIZE 0x400
  8. #define REQUIRED_WINSOCK_VER 0x0101
  9. #define WINSOCK_SUCCESS 0
  10.  
  11. const char CONFIG_FILENAME[] = "config.cfg";
  12.  
  13. HANDLE STDOUT_HANDLE;
  14. const int CONSOLE_WIDTH = 80;
  15. const int CONSOLE_HEIGTH = 23;
  16. const int DISPLAYED_CONNECTIONS_LIMIT = 23 - 6;
  17. const int CONNECTIONS_LIST_FIRST_RAW_OFFSET = 5;
  18. const int CONNECTIONS_LIST_FIRST_COLUMN_OFFSET = 1;
  19. const int CONNECTIONS_LIST_SECOND_COLUMN_OFFSET = 18;
  20. const COORD UPPER_LEFT_CORNER = {0, 0};
  21. const COORD CONNECTIONS_LIST_FIRST_POSITION = {1, 5};
  22. const COORD LOWER_LEFT_CORNER = {0, 23};
  23.  
  24. const char hello[] =
  25. {
  26.     "Hello from eServer!\n\
  27.     \rType any message to get echo, type ""-close"" to exit\n"
  28. };
  29.  
  30. const int MAX_CONNECTIONS = 0xFF;
  31.  
  32. const char DEFAULT_INET_ADDR[] = "192.168.1.100";
  33. const int DEFAULT_LISTENING_PORT = 23;
  34.  
  35. CRITICAL_SECTION PRINT_CS;
  36.  
  37. struct
  38. {
  39.     int number_of_clients;
  40.     struct client_info
  41.     {
  42.         int id;
  43.         BOOL is_up;
  44.         HANDLE thread_handle;
  45.         SOCKET client_socket;
  46.         struct in_addr client_address;
  47.     }*client_pool, buff_new_client_info;
  48. }database;
  49.  
  50. void exit_error_in_function( char function[] )
  51. {
  52.     SetConsoleCursorPosition( STDOUT_HANDLE, UPPER_LEFT_CORNER );
  53.     system( "cls" );
  54.     int error = WSAGetLastError();
  55.     printf( "Function %s ERROR %i\n", function, error );
  56.     system( "pause" );
  57.     exit( error );
  58. }
  59.  
  60. void fill_connection_data( struct sockaddr* src, BOOL preset )
  61. {
  62.     static FILE* config;
  63.     static char file_buff[ 0x10 ];
  64.     memset( src, 0, sizeof( *src ) );
  65.  
  66.     if( FALSE == preset )
  67.     {
  68.         config = fopen( CONFIG_FILENAME, "r" );
  69.         if(FALSE == config)
  70.         {
  71.             preset = TRUE;
  72.         }
  73.         else
  74.         {
  75.             ( (struct sockaddr_in*)src )->sin_family = AF_INET;
  76.  
  77.             memset( file_buff, 0, sizeof(file_buff) );
  78.             fgets( file_buff, 16, config );
  79.             ( (struct sockaddr_in*)src )->sin_addr.S_un.S_addr = inet_addr( file_buff );
  80.  
  81.             memset( file_buff, 0, sizeof(file_buff) );
  82.             fgets( file_buff, 16, config );
  83.             ( (struct sockaddr_in*)src )->sin_port = htons( atoi( file_buff ) );
  84.         }
  85.  
  86.  
  87.     }
  88.     if( TRUE == preset )
  89.     {
  90.         ( (struct sockaddr_in*)src )->sin_family = AF_INET;
  91.         ( (struct sockaddr_in*)src )->sin_addr.S_un.S_addr = inet_addr( DEFAULT_INET_ADDR );
  92.         ( (struct sockaddr_in*)src )->sin_port = htons( DEFAULT_LISTENING_PORT );
  93.     }
  94. }
  95.  
  96. void print_interface( struct sockaddr* info )
  97. {
  98.     int i;
  99.     EnterCriticalSection(&PRINT_CS);
  100.     SetConsoleCursorPosition( STDOUT_HANDLE, UPPER_LEFT_CORNER );
  101.     printf( "eServer is listening %s:%i...\n",
  102.            inet_ntoa( ((struct sockaddr_in*)info)->sin_addr ), ntohs( ((struct sockaddr_in*)info)->sin_port ) );
  103.     for(i = 0; i < CONSOLE_WIDTH; i++)
  104.     {
  105.         printf( "-" );
  106.     }
  107.     printf( "\n" );
  108.     printf(" Client ID        Client IP\n");
  109.     LeaveCriticalSection(&PRINT_CS);
  110. }
  111.  
  112. void print_log( char* message, ... )
  113. {
  114.     va_list args;
  115.  
  116.     EnterCriticalSection(&PRINT_CS);
  117.     SetConsoleCursorPosition( STDOUT_HANDLE, LOWER_LEFT_CORNER );
  118.     va_start( args, message );
  119.     vfprintf( stdout, message, args );
  120.     fprintf( stdout, "\n" );
  121.     LeaveCriticalSection(&PRINT_CS);
  122. }
  123.  
  124. void clear_connections_list()
  125. {
  126.     int i, j;
  127.  
  128.     EnterCriticalSection(&PRINT_CS);
  129.     SetConsoleCursorPosition( STDOUT_HANDLE, CONNECTIONS_LIST_FIRST_POSITION );
  130.     for(i = 0; i < DISPLAYED_CONNECTIONS_LIMIT; i++)
  131.     {
  132.         for(j = 0; j < CONSOLE_WIDTH; j++)
  133.         {
  134.             printf(" ");
  135.         }
  136.     }
  137.     LeaveCriticalSection(&PRINT_CS);
  138. }
  139.  
  140. void connections_list_routine()
  141. {
  142.     int i;
  143.     int displayed_connections;
  144.     COORD buff;
  145.  
  146.     while( TRUE )
  147.     {
  148.         clear_connections_list();
  149.         EnterCriticalSection(&PRINT_CS);
  150.         SetConsoleCursorPosition( STDOUT_HANDLE, CONNECTIONS_LIST_FIRST_POSITION );
  151.         for(i = 0, displayed_connections = 0; i < MAX_CONNECTIONS; i++)
  152.         {
  153.             if( TRUE == database.client_pool[i].is_up )
  154.             {
  155.                 if( displayed_connections <= DISPLAYED_CONNECTIONS_LIMIT )
  156.                 {
  157.                     buff.X = CONNECTIONS_LIST_FIRST_COLUMN_OFFSET;
  158.                     buff.Y = CONNECTIONS_LIST_FIRST_RAW_OFFSET + displayed_connections;
  159.                     SetConsoleCursorPosition( STDOUT_HANDLE, buff );
  160.                     printf("%i", i);
  161.  
  162.                     buff.X = CONNECTIONS_LIST_SECOND_COLUMN_OFFSET;
  163.                     SetConsoleCursorPosition( STDOUT_HANDLE, buff );
  164.                     printf("%s\n", inet_ntoa( database.client_pool[i].client_address ) );
  165.  
  166.                     displayed_connections += 1;
  167.                 }
  168.                 else
  169.                 {
  170.                     buff.X = CONNECTIONS_LIST_FIRST_COLUMN_OFFSET;
  171.                     buff.Y = CONNECTIONS_LIST_FIRST_RAW_OFFSET + DISPLAYED_CONNECTIONS_LIMIT + 1;
  172.                     printf("\n");
  173.                     printf("<...>\n");
  174.                 }
  175.             }
  176.  
  177.         } /* FOR client counting loop end */
  178.         printf( " - %i active connections -\n", database.number_of_clients );
  179.         LeaveCriticalSection(&PRINT_CS);
  180.  
  181.         Sleep(2000);
  182.     } /* WHILE main loop end */
  183. }
  184.  
  185. void client_thread_routine( struct client_info* src )
  186. {
  187.     char msg_buff[ BUFFER_SIZE ];
  188.     int received_bytes;
  189.  
  190.     send( src->client_socket, hello, sizeof( hello ), 0 );
  191.  
  192.     received_bytes = recv( src->client_socket, &msg_buff[0], sizeof( msg_buff ), 0 );
  193.     print_log("[LOG] %i bytes received from client %i", received_bytes, src->id);
  194.  
  195.     while( SOCKET_ERROR != received_bytes
  196.         &&
  197.         0 != received_bytes )
  198.     {
  199.         send( src->client_socket, &msg_buff[0], received_bytes, 0 );
  200.         received_bytes = recv( src->client_socket, &msg_buff[0], sizeof( msg_buff ), 0 );
  201.         print_log( "[LOG] %i bytes received from client %i", received_bytes, src->id );
  202.     }
  203.  
  204.     closesocket( src->client_socket );
  205.     src->is_up = FALSE;
  206.     database.number_of_clients -= 1;
  207. }
  208.  
  209. void add_client( SOCKET* src, struct sockaddr* additional_info )
  210. {
  211.     int i;
  212.     BOOL isAdded = FALSE;
  213.     for(i = 0; i < MAX_CONNECTIONS; i++)
  214.     {
  215.         if( FALSE == database.client_pool[i].is_up )
  216.         {
  217.             database.number_of_clients += 1;
  218.             database.client_pool[i].is_up = TRUE;
  219.             database.client_pool[i].id = i;
  220.             memcpy( &(database.client_pool[i].client_socket), src, sizeof( SOCKET ) );
  221.             database.client_pool[i].client_address = ((struct sockaddr_in*)additional_info)->sin_addr;
  222.             database.client_pool[i].thread_handle =
  223.                 CreateThread( 0, 0, (LPTHREAD_START_ROUTINE)&client_thread_routine, &(database.client_pool[i]), 0, 0);
  224.             if(0 == database.client_pool[i].thread_handle)
  225.             {
  226.                 exit_error_in_function( "CreateThread" );
  227.             }
  228.             isAdded = TRUE;
  229.             break;
  230.         }
  231.     }
  232.     if( FALSE == isAdded )
  233.     {
  234.         print_log( "- Connection with %s:%i rejected due to connection limit -",
  235.                   inet_ntoa( ((struct sockaddr_in*)additional_info)->sin_addr ), ntohs( ((struct sockaddr_in*)additional_info)->sin_port ) );
  236.     }
  237. }
  238.  
  239. int main()
  240. {
  241.     char buff[ BUFFER_SIZE ];
  242.     SOCKET server_socket;
  243.     SOCKET buff_socket;
  244.     struct sockaddr server_addr_info;
  245.     char choice;
  246.     BOOL use_default_settings;
  247.  
  248.     InitializeCriticalSection(&PRINT_CS);
  249.     STDOUT_HANDLE = GetStdHandle( STD_OUTPUT_HANDLE );
  250.     database.client_pool = malloc( sizeof( struct client_info ) * MAX_CONNECTIONS );
  251.     memset(database.client_pool, 0, sizeof( struct client_info ) * MAX_CONNECTIONS);
  252.     database.number_of_clients = 0;
  253.  
  254.     if ( WINSOCK_SUCCESS != WSAStartup( REQUIRED_WINSOCK_VER, (WSADATA*)&buff[0] ) )
  255.     {
  256.         exit_error_in_function( "WSAStartup" );
  257.     }
  258.  
  259.     server_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
  260.     if ( INVALID_SOCKET == server_socket )
  261.     {
  262.         exit_error_in_function( "socket" );
  263.     }
  264.  
  265.     printf( "Read settings from config.cfg? (y/n) " );
  266.     choice = getch();
  267.     switch( tolower( choice ) )
  268.     {
  269.         case 'y':
  270.             use_default_settings = FALSE;
  271.             break;
  272.         case 'n':
  273.         default:
  274.             use_default_settings = TRUE;
  275.             break;
  276.     }
  277.  
  278.     fill_connection_data( &server_addr_info, use_default_settings );
  279.     if( SOCKET_ERROR == bind( server_socket, (struct sockaddr*)&server_addr_info, sizeof(server_addr_info) ) )
  280.     {
  281.         exit_error_in_function( "bind" );
  282.     }
  283.  
  284.     if( SOCKET_ERROR == listen( server_socket, MAX_CONNECTIONS ) )
  285.     {
  286.         exit_error_in_function( "listen" );
  287.     }
  288.  
  289.     print_interface( &server_addr_info );
  290.     CreateThread( 0, 0, (LPTHREAD_START_ROUTINE)&connections_list_routine, 0, 0, 0);
  291.     while( TRUE )
  292.     {
  293.         memset(buff, 0, sizeof( struct sockaddr ));
  294.         buff_socket = accept( server_socket, (struct sockaddr*)&buff, 0 );
  295.         if( INVALID_SOCKET == buff_socket )
  296.         {
  297.             exit_error_in_function( "accept" );
  298.         }
  299.         else
  300.         {
  301.             add_client( &buff_socket, (struct sockaddr*)&buff );
  302.         }
  303.     }
  304.  
  305.     return 0;
  306. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement