Advertisement
Guest User

eServer

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