Advertisement
dzungchaos

TCP_Server.cpp

Nov 17th, 2020
1,182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.58 KB | None | 0 0
  1. // LoginServer.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include <stdio.h>
  6. #include <conio.h>
  7. #include <winsock2.h>
  8. #include <ws2tcpip.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #define _CRT_SECURE_NO_WARNINGS
  12. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  13. #define SERVER_PORT 7225
  14. #define SERVER_ADDR "127.0.0.1"
  15. #define BUFF_SIZE 2048
  16. #define MAX_UID_LENGTH 2048
  17. #define MAX_PWD_LENGHT 2048
  18. #undef UNICODE
  19.  
  20. //Error code for USERID
  21. #define USER_OK "00"
  22. #define USER_VOID "01"      // User doesnot exist
  23. #define USER_DISABLED "02"  // User is locked
  24. #define USER_NULL "03"      // User has not entered UID
  25.  
  26. // Error code for PASSWORD
  27. #define PASS_OK "10"
  28. #define PASS_INCORRECT "11"
  29. #define PASS_NULL "12"
  30.  
  31. // Error code for LOGOUT
  32. #define LOGOUT_SUCCESS "20"
  33. #define USER_NOT_AUTHENTICATED "21"
  34.  
  35. // Error code for LOGIN
  36. #define LOGIN_SUCCESS "30"
  37. #define USER_AUTHENTICATED "31"
  38. #define USER_IDENTIFIED "32"
  39. #define USER_ONLINE "33"
  40. #define USER_OFFLINE "34"
  41.  
  42. // Error code for EXIT
  43. #define EXIT_OK  "40"
  44. #define EXIT_FAIL "41"
  45.  
  46. // Other error code
  47. #define SYNTAX_ERROR "51"
  48. #define NO_OPTION "52"
  49. #define UNKNOW_ERROR "53"
  50.  
  51. // Code for kind of message
  52. #define USER_PREFIX "USER"
  53. #define PASSWORD_PREFIX "PASS"
  54. #define LOGOUT_PREFIX "LOUT"
  55. #define LOGIN_PREFIX "LGIN"
  56. #define EXIT_PREFIX "EXIT"
  57. #define OTHER_OPTION "OTHR"
  58.  
  59. // Status for connection
  60. #define AUTHENTICATED 0
  61. #define NOT_AUTHENTICATED 1
  62. #define NOT_IDENTIFIED 2
  63. #define NO_CONNECTION 3
  64.  
  65. // link with Ws2_32.lib
  66. #pragma comment (lib, "Ws2_32.lib")
  67. #pragma warning(disable : 4996)
  68.  
  69. // Declare struct for Account
  70. struct Account {
  71.     char *userID;
  72.     char *password;
  73.     int status; //0: active, 1: disabled
  74.     Account *next;
  75. };
  76.  
  77. Account *head = NULL;
  78. Account *current = NULL;
  79.  
  80. // All function needed to complete the program
  81. Account *getDataFromFile(FILE *file);
  82. void saveDataToFile(FILE *file, Account *aPtr);
  83. char *checkValidUser(Account *aPtr, char *userID);
  84. char *checkValidPassword(Account *aPtr, char *userID, char *password);
  85. void lockUser(FILE *file, char *userID, Account *aPtr, char *oldName);
  86. void printList(Account *aPtr);
  87. char *checkLogout();
  88. char *getPrefix(char *message);
  89. void chopNChars(char *str, int n);
  90. bool isUserID(char *message);
  91. bool isPassword(char *message);
  92. bool isLogOut(char *message);
  93.  
  94.  
  95. int main(int argc, char* argv[]) {
  96.     // Open all necessary files
  97.     char fileName[] = "account.txt";
  98.     FILE *file = fopen(fileName, "r+");
  99.  
  100.     // Create a linked list with the data
  101.     // of the original file
  102.     current = getDataFromFile(file);
  103.  
  104.     // Initiate WinSock
  105.     WSADATA wsaData;
  106.     WORD wVersion = MAKEWORD(2, 2);
  107.     if (WSAStartup(wVersion, &wsaData)) {
  108.         printf("Version is not support!\n");
  109.     }
  110.  
  111.     // Construct socket
  112.     SOCKET listenSock;
  113.     listenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  114.  
  115.     // Bind address to socket
  116.     sockaddr_in serverAddr;
  117.     serverAddr.sin_family = AF_INET;
  118.     serverAddr.sin_port = htons(SERVER_PORT);
  119.     serverAddr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
  120.  
  121.     if (bind(listenSock, (sockaddr *)&serverAddr, sizeof(serverAddr))) {
  122.         printf("Error! Cannot bind this address!\n");
  123.         return 0;
  124.     }
  125.  
  126.     // Listen request from client
  127.     if (listen(listenSock, 10)) {
  128.         printf("Error! Cannot listen!\n");
  129.         return 0;
  130.     }
  131.     printf("Server started!\n");
  132.  
  133.     // Communicate with client
  134.     sockaddr_in clientAddr;
  135.     int ret, clientAddrLen = sizeof(clientAddr);
  136.     int connStat = NO_CONNECTION;
  137.  
  138.     printList(current);
  139.  
  140.     while (1) {
  141.         SOCKET connSock;
  142.         // accept request
  143.         connSock = accept(listenSock, (sockaddr *)&clientAddr, &clientAddrLen);
  144.         printf("Client connected!\n");
  145.         connStat = NOT_IDENTIFIED;
  146.         char uid[BUFF_SIZE] = { '\0' };
  147.         do {
  148.             // Listen menu request from client
  149.             char buff[BUFF_SIZE] = {'\0'};
  150.             int countWrong;
  151.             ret = recv(connSock, buff, BUFF_SIZE, 0);
  152.             if (ret == SOCKET_ERROR)
  153.                 break;
  154.             buff[ret] = 0;
  155.             // Consider the state of the connection
  156.  
  157.             // User hasnot entered any information
  158.             if (connStat == NOT_IDENTIFIED) {
  159.                 if (strcmp(getPrefix(buff), USER_PREFIX) == 0) {
  160.                     chopNChars(buff, 4);
  161.                     strcpy(uid, buff);
  162.                     printf("UID %s\n", uid);
  163.                     // Handle the message
  164.                     // Username is not null
  165.                     if (strlen(buff) > 0) {
  166.                         printf("Receive from client1 %s\n", buff);
  167.  
  168.                         // Check if the UserID is valid
  169.                         if ((strcmp(checkValidUser(current, buff), USER_OK) == 0)) {
  170.                             printf("Valid UserID!\n");
  171.                             connStat = NOT_AUTHENTICATED;
  172.                             countWrong = 0;
  173.  
  174.                             // Echo success code to client
  175.                             ret = send(connSock, USER_OK, strlen(USER_OK), 0);
  176.                             if (ret == SOCKET_ERROR)
  177.                                 printf("Error 2 : %i\n", WSAGetLastError());
  178.                         }
  179.                         // UserID doesnot not exist
  180.                         else if (strcmp(checkValidUser(current, buff), USER_VOID) == 0) {
  181.                             printf("UserID does not exist!\n");
  182.  
  183.                             // Echo error code to client
  184.                             ret = send(connSock, USER_VOID, strlen(USER_VOID), 0);
  185.                             if (ret == SOCKET_ERROR)
  186.                                 printf("Error 3 : %i\n", WSAGetLastError());
  187.                         }
  188.                         // UserID is disabled
  189.                         else if (strcmp(checkValidUser(current, buff), USER_DISABLED) == 0) {
  190.                             printf("User is disabled!\n");
  191.  
  192.                             // Echo error code to client
  193.                             ret = send(connSock, USER_DISABLED, strlen(USER_DISABLED), 0);
  194.                             if (ret == SOCKET_ERROR)
  195.                                 printf("Error 3 : %i\n", WSAGetLastError());
  196.                         }
  197.                     }
  198.  
  199.                     // Username is null
  200.                     else if (strlen(buff) <= 0) {
  201.                         printf("Receive from client %s\n", buff);
  202.                         printf("UserID is NULL!\n");
  203.                         ret = send(connSock, USER_NULL, strlen(USER_NULL), 0);
  204.                         // printf("8\n");
  205.                         if (ret == SOCKET_ERROR)
  206.                             printf("Error : %i\n", WSAGetLastError());
  207.                         // printf("9\n");
  208.                     }
  209.                 }
  210.                 else if (strcmp(getPrefix(buff), PASSWORD_PREFIX) == 0) {
  211.                     ret = send(connSock, SYNTAX_ERROR, strlen(SYNTAX_ERROR), 0);
  212.                     if (ret == SOCKET_ERROR)
  213.                         printf("Error : %i\n", WSAGetLastError());
  214.                 }
  215.                 else if (strcmp(getPrefix(buff), LOGOUT_PREFIX) == 0) {
  216.                     ret = send(connSock, USER_NOT_AUTHENTICATED, strlen(USER_NOT_AUTHENTICATED), 0);
  217.                     if (ret == SOCKET_ERROR)
  218.                         printf("Error : %i\n", WSAGetLastError());
  219.                 }
  220.                 else if (strcmp(getPrefix(buff), EXIT_PREFIX) == 0) {
  221.                     ret = send(connSock, EXIT_OK, strlen(EXIT_OK), 0);
  222.                     if (ret == SOCKET_ERROR)
  223.                         printf("Error : %i\n", WSAGetLastError());
  224.                     connStat = NO_CONNECTION;
  225.                     break;
  226.                 }
  227.                 else if (strcmp(getPrefix(buff), OTHER_OPTION) == 0) {
  228.                     ret = send(connSock, NO_OPTION, strlen(NO_OPTION), 0);
  229.                     if (ret == SOCKET_ERROR)
  230.                         printf("Error : %i\n", WSAGetLastError());
  231.                 }
  232.                 else {
  233.                     ret = send(connSock, UNKNOW_ERROR, strlen(UNKNOW_ERROR), 0);
  234.                     if (ret == SOCKET_ERROR)
  235.                         printf("Error : %i\n", WSAGetLastError());
  236.                 }
  237.             }
  238.  
  239.             // User enter the userid and being identified
  240.             else if (connStat == NOT_AUTHENTICATED) {
  241.                 if (strcmp(getPrefix(buff), PASSWORD_PREFIX) == 0) {
  242.                     printf("%s\n", buff);
  243.                     chopNChars(buff, 4);
  244.                     printf("%s\n", buff);
  245.                     printf("uid %s\n", uid);
  246.                     // Check if the received password is NULL
  247.                     if (strlen(buff) > 0) {
  248.                         printf("Receive from client2 %s\n", buff);
  249.  
  250.                         // Check if the password is correct
  251.                         if (strcmp(checkValidPassword(current, uid, buff), PASS_OK) == 0) {
  252.                             printf("Correct password!\n");
  253.                             connStat = AUTHENTICATED;
  254.                             countWrong = 0;
  255.  
  256.                             // Echo success code to client
  257.                             ret = send(connSock, PASS_OK, strlen(PASS_OK), 0);
  258.                             if (ret == SOCKET_ERROR)
  259.                                 printf("Error 2.2 : %i\n", WSAGetLastError());
  260.                             break;
  261.                         }
  262.  
  263.                         // The password is incorrect
  264.                         else if ((strcmp(checkValidPassword(current, uid, buff), PASS_INCORRECT) == 0) && (countWrong < 2)) {
  265.                             printf("Count wrong %d\n", countWrong);
  266.                             printf("Incorrect password!\n");
  267.                             countWrong++;
  268.  
  269.                             // Echo error code to client
  270.                             ret = send(connSock, PASS_INCORRECT, strlen(PASS_INCORRECT), 0);
  271.                             if (ret == SOCKET_ERROR)
  272.                                 printf("Error 2.3 : %i\n", WSAGetLastError());
  273.                         }
  274.  
  275.                         // The userID is disabled after 3 times entering wrong password
  276.                         else if (countWrong == 2) {
  277.                             printf("UserID is disabled!\n");
  278.                             connStat = NOT_IDENTIFIED;
  279.                             lockUser(file, uid, current, fileName);
  280.  
  281.                             ret = send(connSock, USER_DISABLED, strlen(USER_DISABLED), 0);
  282.                             if (ret == SOCKET_ERROR)
  283.                                 printf("Error 2.4 : %i\n", WSAGetLastError());
  284.                         }
  285.  
  286.                         // UserID is disabled
  287.                         else if (strcmp(checkValidUser(current, uid), USER_DISABLED) == 0) {
  288.                             printf("User is disabled!\n");
  289.  
  290.                             // Echo error code to client
  291.                             ret = send(connSock, USER_DISABLED, strlen(USER_DISABLED), 0);
  292.                             if (ret == SOCKET_ERROR)
  293.                                 printf("Error 3 : %i\n", WSAGetLastError());
  294.                         }
  295.                     }
  296.                     else if (strlen(buff) <= 0) {
  297.                         printf("Receive from client %s\n", buff);
  298.                         printf("Password is NULL!\n");
  299.                         ret = send(connSock, PASS_INCORRECT, strlen(PASS_INCORRECT), 0);
  300.                         // printf("8\n");
  301.                         if (ret == SOCKET_ERROR)
  302.                             printf("Error : %i\n", WSAGetLastError());
  303.                     }
  304.                 }
  305.                 else if (strcmp(getPrefix(buff), USER_PREFIX) == 0) {
  306.                     ret = send(connSock, SYNTAX_ERROR, strlen(SYNTAX_ERROR), 0);
  307.                     if (ret == SOCKET_ERROR)
  308.                         printf("Error : %i\n", WSAGetLastError());
  309.                 }
  310.                 else if (strcmp(getPrefix(buff), LOGOUT_PREFIX) == 0) {
  311.                     ret = send(connSock, USER_NOT_AUTHENTICATED, strlen(USER_NOT_AUTHENTICATED), 0);
  312.                     if (ret == SOCKET_ERROR)
  313.                         printf("Error : %i\n", WSAGetLastError());
  314.                 }
  315.                 else if (strcmp(getPrefix(buff), EXIT_PREFIX) == 0) {
  316.                     ret = send(connSock, EXIT_OK, strlen(EXIT_OK), 0);
  317.                     if (ret == SOCKET_ERROR)
  318.                         printf("Error : %i\n", WSAGetLastError());
  319.                     connStat = NO_CONNECTION;
  320.                     break;
  321.                 }
  322.                 else if (strcmp(getPrefix(buff), OTHER_OPTION) == 0) {
  323.                     ret = send(connSock, NO_OPTION, strlen(NO_OPTION), 0);
  324.                     if (ret == SOCKET_ERROR)
  325.                         printf("Error : %i\n", WSAGetLastError());
  326.                 }
  327.                 else {
  328.                     ret = send(connSock, UNKNOW_ERROR, strlen(UNKNOW_ERROR), 0);
  329.                     if (ret == SOCKET_ERROR)
  330.                         printf("Error : %i\n", WSAGetLastError());
  331.                 }
  332.             }
  333.  
  334.             // Userid has been logged in to the system
  335.             else if (connStat == AUTHENTICATED) {
  336.                 if (strcmp(getPrefix(buff), USER_PREFIX) == 0) {
  337.                     ret = send(connSock, USER_AUTHENTICATED, strlen(USER_AUTHENTICATED), 0);
  338.                     if (ret == SOCKET_ERROR)
  339.                         printf("Error : %i\n", WSAGetLastError());
  340.                 }
  341.                 else if (strcmp(getPrefix(buff), PASSWORD_PREFIX) == 0) {
  342.                     ret = send(connSock, USER_AUTHENTICATED, strlen(USER_AUTHENTICATED), 0);
  343.                     if (ret == SOCKET_ERROR)
  344.                         printf("Error : %i\n", WSAGetLastError());
  345.                 }
  346.                 else if (strcmp(getPrefix(buff), LOGOUT_PREFIX) == 0) {
  347.                     ret = send(connSock, LOGOUT_SUCCESS, strlen(LOGOUT_SUCCESS), 0);
  348.                     if (ret == SOCKET_ERROR)
  349.                         printf("Error : %i\n", WSAGetLastError());
  350.                     connStat = NOT_IDENTIFIED;
  351.                 }
  352.                 else if (strcmp(getPrefix(buff), EXIT_PREFIX) == 0) {
  353.                     ret = send(connSock, EXIT_OK, strlen(EXIT_OK), 0);
  354.                     if (ret == SOCKET_ERROR)
  355.                         printf("Error : %i\n", WSAGetLastError());
  356.                     connStat = NO_CONNECTION;
  357.                     break;
  358.                 }
  359.                 else if (strcmp(getPrefix(buff), OTHER_OPTION) == 0) {
  360.                     ret = send(connSock, NO_OPTION, strlen(NO_OPTION), 0);
  361.                     if (ret == SOCKET_ERROR)
  362.                         printf("Error : %i\n", WSAGetLastError());
  363.                 }
  364.                 else {
  365.                     ret = send(connSock, UNKNOW_ERROR, strlen(UNKNOW_ERROR), 0);
  366.                     if (ret == SOCKET_ERROR)
  367.                         printf("Error : %i\n", WSAGetLastError());
  368.                 }
  369.             }
  370.         } while (connStat != NO_CONNECTION);
  371.         closesocket(connSock);
  372.     } // end accepting
  373.  
  374.       // Close socket
  375.     closesocket(listenSock);
  376.  
  377.     // Terminate Winsock
  378.     WSACleanup();
  379.  
  380.     return 0;
  381. }
  382.  
  383.  
  384. // Return a singly linked list with the
  385. // data as from pointed file
  386. Account *getDataFromFile(FILE *file) {
  387.     Account *current;               // pointer points to the current data
  388.     char userID[MAX_UID_LENGTH];
  389.     char password[MAX_PWD_LENGHT];
  390.     int status;                     // status of the account (0 is active, 1 is deactive)
  391.  
  392.     current = NULL;
  393.  
  394.     // Traverse to the end of file
  395.     while (!feof(file)) {
  396.         // Extract data from file
  397.         fscanf(file, "%s %s %d", userID, password, &status);
  398.  
  399.         // Assign data to the current pointer
  400.         Account *node = new Account;
  401.         node->userID = strdup(userID);
  402.         node->password = strdup(password);
  403.         node->status = status;
  404.         node->next = NULL;
  405.  
  406.         if (head == NULL)
  407.             head = current = node;
  408.         else
  409.             current = current->next = node;
  410.     }
  411.  
  412.     return current;
  413. }
  414.  
  415.  
  416. // Save the data from the pointed linked
  417. // list to a specific file
  418. void saveDataToFile(FILE *file, Account *aPtr) {
  419.     for (aPtr = head; aPtr; aPtr = aPtr->next) {
  420.         // This if - else is to make the last character not '\n'
  421.         if (aPtr->next != NULL)
  422.             fprintf(file, "%s %s %d\n", aPtr->userID, aPtr->password, aPtr->status);
  423.         else
  424.             fprintf(file, "%s %s %d", aPtr->userID, aPtr->password, aPtr->status);
  425.     }
  426. }
  427.  
  428. // Print the data of the linked list
  429. // (for testing only)
  430. void printList(Account *aPtr) {
  431.     for (aPtr = head; aPtr; aPtr = aPtr->next)
  432.         printf("%s %s %d\n", aPtr->userID, aPtr->password, aPtr->status);
  433. }
  434.  
  435. // Return a signal to send back userID
  436. // handled result to the client
  437. // The parameters is a data pointer and userID
  438. char *checkValidUser(Account *aPtr, char *userID) {
  439.     for (aPtr = head; aPtr; aPtr = aPtr->next)
  440.         if ((strcmp(aPtr->userID, userID) == 0) && (aPtr->status == 0))
  441.             return USER_OK;
  442.         else if ((strcmp(aPtr->userID, userID) == 0) && (aPtr->status == 1))
  443.             return USER_DISABLED;
  444.  
  445.     return USER_VOID;
  446. }
  447.  
  448.  
  449. // Return a signal to send back password
  450. // handled result to the client
  451. // The parameters is a data pointer, userID and password
  452. char *checkValidPassword(Account *aPtr, char *userID, char *password) {
  453.     for (aPtr = head; aPtr; aPtr = aPtr->next)
  454.         if ((strcmp(aPtr->userID, userID) == 0) && (aPtr->status == 0) && (strcmp(aPtr->password, password) == 0))
  455.             return PASS_OK;
  456.  
  457.     return PASS_INCORRECT;
  458. }
  459.  
  460.  
  461. // This function is to lock user when
  462. // the password is incorrect 3 times
  463. // The parameter includes: file pointer,
  464. // userID to be disabled, data pointer
  465. // and the name of the pointed file
  466. void lockUser(FILE *file, char *userID, Account *aPtr, char *oldName) {
  467.     // Change the status to 1 (disabled)
  468.     freopen(oldName, "w+", file);
  469.     for (aPtr = head; aPtr; aPtr = aPtr->next) {
  470.         if (strcmp(aPtr->userID, userID) == 0) {
  471.             aPtr->status = 1;
  472.         }
  473.     }
  474.  
  475.     printf("\tLOCKED ACCOUNT %s !\n", userID);
  476.     saveDataToFile(file, aPtr);
  477.     freopen(oldName, "r+", file);
  478. }
  479.  
  480.  
  481. // Check if the logout command is available
  482. char *checkLogout() {
  483.     return LOGOUT_SUCCESS;
  484. }
  485.  
  486.  
  487. // Get prefix of a message from client
  488. char *getPrefix(char *message) {
  489.     char *pre = new char[5];
  490.     int c;
  491.  
  492.     if (pre == NULL) {
  493.         printf("Error!\n");
  494.         exit(1);
  495.     }
  496.  
  497.     for (c = 0; c < 4; c++) {
  498.         *(pre + c) = *(message);
  499.         message++;
  500.     }
  501.  
  502.     *(pre + c) = '\0';
  503.  
  504.     return pre;
  505. }
  506.  
  507.  
  508. // Check if the message is UserID
  509. bool isUserID(char *message) {
  510.     if (strcmp(getPrefix(message), USER_PREFIX) == 0) {
  511.         return true;
  512.     }
  513.     return false;
  514. }
  515.  
  516.  
  517. // Check if the message is Password
  518. bool isPassword(char *message) {
  519.     if (strcmp(getPrefix(message), PASSWORD_PREFIX) == 0)
  520.         return true;
  521.     return false;
  522. }
  523.  
  524.  
  525. // Check if the message is Logout cmd
  526. bool isLogOut(char *message) {
  527.     if (strcmp(getPrefix(message), LOGOUT_PREFIX) == 0)
  528.         return true;
  529.     return false;
  530. }
  531.  
  532.  
  533. // Function to cut n first character of
  534. // a pointed string
  535. void chopNChars(char *str, int n) {
  536.     int strLen = strlen(str);
  537.     if (n > strLen)
  538.         return;
  539.     memmove(str, str + n, strLen - n + 1);
  540. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement