Advertisement
Guest User

Untitled

a guest
Mar 14th, 2019
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.21 KB | None | 0 0
  1. #include <string>
  2. #include <WinSock2.h>
  3. #include <iostream>
  4. #include <fstream>
  5. #include <ctime>
  6. #include <sstream>
  7. #include "Serwer.hpp"
  8.  
  9. using namespace std;
  10.  
  11. Serwer::Serwer(){};
  12.  
  13. Serwer::Serwer(int port){
  14.     Initialization(port);
  15. }
  16.  
  17. void Serwer::Initialization(int port){
  18.     logIn = isClientActive = false;
  19.     strcpy(userKey, "");
  20.     strcpy(userName, "");
  21.     strcpy(userPw, "");
  22.     clearPacket(packetOUT);
  23.     WSAStartup( MAKEWORD(2,2), &wsaData );
  24.     sequenceNumber = 0;
  25.     sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  26.     // aktywacja trybu non-blocking
  27.     u_long iMode = 0;
  28.     ioctlsocket(sock, FIONBIO, &iMode);
  29.     // +
  30.     char options = '1';
  31.     setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &options, sizeof(int));
  32.     saddr.sin_family = AF_INET;
  33.     saddr.sin_port = htons(port);
  34.     saddr.sin_addr.s_addr = htonl(INADDR_ANY);
  35. }
  36.  
  37. int Serwer::mainLoop(){
  38.     if (bind(sock, (sockaddr*)&saddr, sizeof(saddr)) != SOCKET_ERROR)
  39.     {
  40.         SOCKET clientSocket;
  41.  
  42.         cout << "Wiadomosc systemowa: Serwer uruchomiony poprawnie" << endl;
  43.  
  44.         while (1)
  45.         {
  46.             if (listen(sock, 10) != SOCKET_ERROR)
  47.             {
  48.                 if (!isClientActive)
  49.                 {
  50.                     int sizeOfsAddress = sizeof(saddr);
  51.                     clientSocket = accept(sock,(sockaddr*)&saddr, &sizeOfsAddress);
  52.                     isClientActive = true;
  53.                     system("CLS");
  54.                     cout << "Wiadomosc systemowa: Klient podlaczyl sie" << endl;
  55.                 }
  56.                 clearPacket(packetIN);
  57.                 int dataLength = 0;
  58.                 dataLength = recv(clientSocket, (char *)&packetIN, sizeof(packetIN)-sizeof(packetIN.Payload), 0);
  59.                      recv(clientSocket,(char *)packetIN.Payload,packetIN.payloadLength,0);
  60.                 //int nError=WSAGetLastError();
  61.  
  62.                 if ((dataLength == -1) || (dataLength == 0))
  63.                 {
  64.                     disconnect(&clientSocket);
  65.                     cout << "Wiadomosc systemowa: Klient rozlaczyl sie" << endl;
  66.                 }
  67.                 sequenceNumber = packetIN.Identifier;
  68.                 decodeMethod(packetIN.Method, &clientSocket);
  69.             }  
  70.         }
  71.         closesocket(clientSocket);
  72.     }
  73.  
  74.     closesocket(sock);
  75.     WSACleanup();
  76.     return 0;
  77. }
  78.  
  79. int Serwer::sendMsg(SOCKET *clientSocket)
  80. {
  81.     // tutaj musi znaleźć się kompletna obsługa fragmentacji plików o ile taką chcemy wprowadzić
  82.     return send(*clientSocket, (char *)&packetOUT, sizeof(packetOUT)-sizeof(packetOUT.Payload)+packetOUT.payloadLength, 0);
  83. }
  84.  
  85. // funkcja odpowiedzialna za rozłączanie klienta
  86. bool Serwer::disconnect(SOCKET *clientS)
  87. {
  88.     isClientActive = false;
  89.     logIn = false;
  90.     closesocket(*clientS);
  91.     return true;
  92. }
  93.  
  94. // generuje struktuę pakietu danych (głownie wyjściowego)
  95. bool Serwer::generatePacket(packet &pack, short int method, char *key, char *msg)
  96. {
  97.     pack.Identifier = sequenceNumber;
  98.     pack.Method = method;
  99.     pack.Expires = 900;
  100.     strcpy(pack.Key, key);
  101.     strcpy(pack.Payload, msg);
  102.     pack.payloadLength = strlen(pack.Payload)+1;
  103.     return true;
  104. }
  105.  
  106. // czyści strukturę pakietu danych (głównie wejściowego)
  107. bool Serwer::clearPacket(packet &pack)
  108. {
  109.     pack.Identifier = 0;
  110.     pack.Method = 0;
  111.     pack.Expires = 900;
  112.     strcpy(pack.Key, "");
  113.     strcpy(pack.Payload, "");
  114.     pack.payloadLength = strlen(pack.Payload);
  115.     return true;
  116. }
  117. //Funkcja sprawdza czy dane sa poprawne i loguje uzytkownika
  118. bool Serwer::login(string login, string pass){
  119.     fstream File;
  120.     size_t pos;
  121.     File.open("users.db", std::ios::in);
  122.     if( !File.good())
  123.     {
  124.         return false;
  125.     }
  126.     string temp,username,password;
  127.     while(!File.eof()){
  128.         getline(File, temp);
  129.         if(temp.length() != 0){
  130.             pos = temp.find("?");
  131.             if(pos != 0){
  132.                 username = temp.substr(0, pos);
  133.                 password = temp.substr(pos+1);
  134.                 if(username == login && password == pass){
  135.                     File.close();
  136.                     return true;
  137.                 }
  138.             }
  139.         }
  140.        
  141.     }
  142.     File.close();
  143.     return false;
  144. }
  145. //Funkcja sprawdza, czy dana nazwa znajduje sie w bazie
  146. bool Serwer::isRegistred(string login){
  147.     fstream File;
  148.     size_t pos;
  149.     File.open("users.db", std::ios::in);
  150.     if( !File.good())
  151.     {
  152.         fstream("users.db", ios::out).close();
  153.         File.open("users.db", std::ios::in);
  154.     }
  155.     string temp,username,password;
  156.     while(!File.eof()){
  157.         getline(File, temp);
  158.         if(temp.length() != 0){
  159.             pos = temp.find("?");
  160.             if(pos != 0){
  161.                 username = temp.substr(0, pos);
  162.                 if(username == login){
  163.                     File.close();
  164.                     return true;
  165.                 }
  166.             }
  167.         }
  168.        
  169.     }
  170.     File.close();
  171.     return false;
  172. }
  173. //Funkcja zapisuje do pliku dane o uzytkowniku
  174. void Serwer::Register(string login, string pass){
  175.     fstream File;
  176.     File.open("users.db", std::ios::out | ios::app);
  177.     string temp;
  178.     temp = login;
  179.     temp += "?";
  180.     temp += pass;
  181.     temp += "\n";
  182.     File << temp;
  183.     File.close();
  184. }
  185.  
  186. // gruba funkcja odpowiedzialna za dekodowanie METOD i wykonanie odpowiednich działań z nimi związanych
  187. bool Serwer::decodeMethod(int method, SOCKET *clientSocket)
  188. {
  189.     switch (method)
  190.     {
  191.         case 1: // rejestracja
  192.             {
  193.                 if (logIn == false)
  194.                 {
  195.                     string tmp = packetIN.Payload;
  196.                     int delimeterPos = tmp.find('?');
  197.                     string tmpLogin = tmp.substr(0, delimeterPos);
  198.                     string tmpPass = tmp.substr(delimeterPos+1, tmp.length());
  199.                     generatePacket(packetOUT, 5, "", "Pomyslnie zarejestrowano uzytkownika");
  200.                     if(isRegistred(tmpLogin)){
  201.                         cout << "Wiadomosc systemowa: Klient o podanej nazwie istnieje juz w bazie danych!" << endl;
  202.                         generatePacket(packetOUT, 6, "", "Uzytkownik o tej nazwie istnieje juz w bazie danych!");
  203.                     }else{
  204.                         if ((tmpLogin.length() > 2) && (tmpPass.length() > 2))
  205.                         {
  206.                             // w naszym przypadku moze być tylko jeden zarejestrowany uzytkownik (można rozbudować)
  207.                             // w takim układzie dane są nadpisywane i nie jest sprawdzane, czy użytkownik o takim loginie istnieje
  208.                             strcpy(userName, tmpLogin.c_str());
  209.                             strcpy(userPw, tmpPass.c_str());
  210.                             Register(tmpLogin.c_str(), tmpPass.c_str());
  211.                             cout << "Wiadomosc systemowa: Klient zarejestowal sie(" << userName << ")" << endl;
  212.                             generatePacket(packetOUT, 5, "", "Pomyslnie zarejestrowano uzytkownika");
  213.                         }
  214.                         else
  215.                         {
  216.                             cout << "Wiadomosc systemowa: Klient podal niepoprawne dane! Rejestracja nie powiodla sie" << endl;
  217.                             generatePacket(packetOUT, 6, "", "Login lub haslo jest nieprawidlowy (minimum 3 znaki)!");
  218.                         }
  219.                     }
  220.                 }
  221.                 else
  222.                 {
  223.                     cout << "Wiadomosc systemowa: Klient probowal utworzyc konto (jest zalogowany!)" << endl;
  224.                     generatePacket(packetOUT, 6, userKey, "Nie mozesz zarejestrowac konta jako zalogowany uzytkownik!");
  225.                 }
  226.                 sendMsg(clientSocket);
  227.  
  228.                 break;
  229.             }
  230.         case 2: // logowanie
  231.             {
  232.                 if (logIn == false)
  233.                 {
  234.                     string tmp = packetIN.Payload;
  235.                     int delimeterPos = tmp.find('?');
  236.                     string tmpLogin = tmp.substr(0, delimeterPos);
  237.                     string tmpPass = tmp.substr(delimeterPos+1, tmp.length());
  238.                    
  239.  
  240.                     // warto wprowadzić obsługę sprawdzania danych z tymi z pliku
  241.                     if (login(tmpLogin, tmpPass))
  242.                     {
  243.                         strcpy(userName, tmpLogin.c_str());
  244.                         logIn = true;
  245.                         int temp;
  246.                         srand(unsigned(time(NULL)));
  247.                         strcpy(userKey, "");
  248.                         for(int i = 0 ; i < 7 ; i++){
  249.                             temp = rand()%2;
  250.                             if(temp){
  251.                                 userKey[i] = (char)((rand()%58) + 65);
  252.                             }else{
  253.                                 userKey[i] = (char)((rand()%10) + 48);
  254.                             }
  255.                         }
  256.                        
  257.                         userKey[7] = '\0';
  258.                         /*ostringstream randStream;
  259.                         randStream << rand()%1000;
  260.                         string tKey = randStream.str();
  261.  
  262.                         strcpy(userKey, tKey.c_str());
  263.                         strcat(userKey, "ukey5");*/
  264.                         // można wymyślić coś ambitniejszego, ale po co?
  265.  
  266.                         cout << "Wiadomosc systemowa: Klient zalogowal sie(" << userName << ")" << endl;
  267.                         generatePacket(packetOUT, 5, userKey, "Pomyslnie zalogowano do systemu");
  268.                     }
  269.                     else
  270.                     {
  271.                         cout << "Wiadomosc systemowa: Klient podal niepoprawne dane! Logowanie nie powiodlo sie" << endl;
  272.                         generatePacket(packetOUT, 6, "", "Login lub haslo jest nieprawidlowy!");
  273.                     }
  274.                 }
  275.                 else
  276.                 {
  277.                     cout << "Wiadomosc systemowa: Klient probowal zalogowac sie (sesja juz istnieje!)" << endl;
  278.                     generatePacket(packetOUT, 6, userKey, "Jestes juz zalogowany!");
  279.                 }
  280.                 sendMsg(clientSocket);
  281.  
  282.                 break;
  283.             }
  284.         case 3: // wylogowywanie
  285.             {
  286.                 if (logIn == true)
  287.                 {
  288.                     logIn = false;
  289.                     cout << "Wiadomosc systemowa: " << userName << " - wylogowal sie!" << endl;
  290.                     strcpy(userKey, "");
  291.                     strcpy(userPw, "");
  292.                     strcpy(userName, "");
  293.                     generatePacket(packetOUT, 5, "", "Poprawnie wylogowano!");
  294.                 }
  295.                 else
  296.                 {
  297.                     cout << "Wiadomosc systemowa: Klient probowal sie wylogowac (sesja nie istnieje!)" << endl;
  298.                     generatePacket(packetOUT, 6, "", "Nie jestes zalogowany!");
  299.                 }
  300.  
  301.                 sendMsg(clientSocket);
  302.  
  303.                 break;
  304.             }
  305.         case 4: // wiadomość tekstowa
  306.             {
  307.                 if (logIn == true)
  308.                 {
  309.                     if(strcmp(packetIN.Key, userKey) == 0){
  310.                         cout << "Wiadomosc systemowa: " << userName << " napisal(a): " << packetIN.Payload << endl;
  311.                         generatePacket(packetOUT, 5, userKey, "Wiadomosc odebrana na serwerze!");
  312.                     }else{
  313.                         logIn = false;
  314.                         strcpy(userKey, "");
  315.                         cout << "Wiadomosc systemowa: " << userName << " - blad sesji" << endl;
  316.                         generatePacket(packetOUT, 6, "", "Identyfikator sesji jest niepoprawny! Zaloguj sie ponownie!");
  317.                     }                  
  318.                 }
  319.                 else
  320.                 {
  321.                     cout << "Wiadomosc systemowa: Klient wyslal wiadomosc tekstowa, ale nie jest zalogowany!" << endl;
  322.                     generatePacket(packetOUT, 6, "", "Nie jestes zalogowany!");
  323.                 }
  324.                 sendMsg(clientSocket);
  325.                 break;
  326.             }
  327.         case 5: // OK
  328.             {
  329.                 cout << "Operacja wykonana pomyslnie!" << endl << "Tresc komunikatu: " << packetIN.Payload << endl;
  330.                 break;
  331.             }
  332.         case 6: // Błąd
  333.             {
  334.                 cout << "Wystapil blad!" << endl << "Tresc komunikatu: " << packetIN.Payload << endl;
  335.                 break;
  336.             }
  337.         case 7: // Rozłączenie
  338.             {
  339.                 if (isClientActive)
  340.                 {
  341.                     cout << "Wiadomosc systemowa: Klient rozlaczyl sie" << endl;
  342.                     generatePacket(packetOUT, 5, "", "Rozlaczono!");
  343.                     sendMsg(clientSocket);
  344.                     disconnect(clientSocket);  
  345.                 }
  346.                 else
  347.                     cout << "Wiadomosc systemowa: Klient probowal sie rozlaczyc (polaczenie nie istnieje!)" << endl;
  348.                    
  349.                 break;
  350.             }
  351.         default: return false;
  352.     }
  353.  
  354.     return true;
  355. }
  356.  
  357. void Serwer::showPacket(packet pack){
  358.     cout << pack.Identifier << endl;
  359.     cout << pack.Method << endl;
  360.     cout << pack.Expires << endl;
  361.     cout << pack.Key << endl;
  362.     cout << pack.payloadLength << endl;
  363.     cout << pack.Payload << endl;
  364. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement