Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string>
- #include <WinSock2.h>
- #include <iostream>
- #include <fstream>
- #include <ctime>
- #include <sstream>
- #include "Serwer.hpp"
- using namespace std;
- Serwer::Serwer(){};
- Serwer::Serwer(int port){
- Initialization(port);
- }
- void Serwer::Initialization(int port){
- logIn = isClientActive = false;
- strcpy(userKey, "");
- strcpy(userName, "");
- strcpy(userPw, "");
- clearPacket(packetOUT);
- WSAStartup( MAKEWORD(2,2), &wsaData );
- sequenceNumber = 0;
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- // aktywacja trybu non-blocking
- u_long iMode = 0;
- ioctlsocket(sock, FIONBIO, &iMode);
- // +
- char options = '1';
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &options, sizeof(int));
- saddr.sin_family = AF_INET;
- saddr.sin_port = htons(port);
- saddr.sin_addr.s_addr = htonl(INADDR_ANY);
- }
- int Serwer::mainLoop(){
- if (bind(sock, (sockaddr*)&saddr, sizeof(saddr)) != SOCKET_ERROR)
- {
- SOCKET clientSocket;
- cout << "Wiadomosc systemowa: Serwer uruchomiony poprawnie" << endl;
- while (1)
- {
- if (listen(sock, 10) != SOCKET_ERROR)
- {
- if (!isClientActive)
- {
- int sizeOfsAddress = sizeof(saddr);
- clientSocket = accept(sock,(sockaddr*)&saddr, &sizeOfsAddress);
- isClientActive = true;
- system("CLS");
- cout << "Wiadomosc systemowa: Klient podlaczyl sie" << endl;
- }
- clearPacket(packetIN);
- int dataLength = 0;
- dataLength = recv(clientSocket, (char *)&packetIN, sizeof(packetIN)-sizeof(packetIN.Payload), 0);
- recv(clientSocket,(char *)packetIN.Payload,packetIN.payloadLength,0);
- //int nError=WSAGetLastError();
- if ((dataLength == -1) || (dataLength == 0))
- {
- disconnect(&clientSocket);
- cout << "Wiadomosc systemowa: Klient rozlaczyl sie" << endl;
- }
- sequenceNumber = packetIN.Identifier;
- decodeMethod(packetIN.Method, &clientSocket);
- }
- }
- closesocket(clientSocket);
- }
- closesocket(sock);
- WSACleanup();
- return 0;
- }
- int Serwer::sendMsg(SOCKET *clientSocket)
- {
- // tutaj musi znaleźć się kompletna obsługa fragmentacji plików o ile taką chcemy wprowadzić
- return send(*clientSocket, (char *)&packetOUT, sizeof(packetOUT)-sizeof(packetOUT.Payload)+packetOUT.payloadLength, 0);
- }
- // funkcja odpowiedzialna za rozłączanie klienta
- bool Serwer::disconnect(SOCKET *clientS)
- {
- isClientActive = false;
- logIn = false;
- closesocket(*clientS);
- return true;
- }
- // generuje struktuę pakietu danych (głownie wyjściowego)
- bool Serwer::generatePacket(packet &pack, short int method, char *key, char *msg)
- {
- pack.Identifier = sequenceNumber;
- pack.Method = method;
- pack.Expires = 900;
- strcpy(pack.Key, key);
- strcpy(pack.Payload, msg);
- pack.payloadLength = strlen(pack.Payload)+1;
- return true;
- }
- // czyści strukturę pakietu danych (głównie wejściowego)
- bool Serwer::clearPacket(packet &pack)
- {
- pack.Identifier = 0;
- pack.Method = 0;
- pack.Expires = 900;
- strcpy(pack.Key, "");
- strcpy(pack.Payload, "");
- pack.payloadLength = strlen(pack.Payload);
- return true;
- }
- //Funkcja sprawdza czy dane sa poprawne i loguje uzytkownika
- bool Serwer::login(string login, string pass){
- fstream File;
- size_t pos;
- File.open("users.db", std::ios::in);
- if( !File.good())
- {
- return false;
- }
- string temp,username,password;
- while(!File.eof()){
- getline(File, temp);
- if(temp.length() != 0){
- pos = temp.find("?");
- if(pos != 0){
- username = temp.substr(0, pos);
- password = temp.substr(pos+1);
- if(username == login && password == pass){
- File.close();
- return true;
- }
- }
- }
- }
- File.close();
- return false;
- }
- //Funkcja sprawdza, czy dana nazwa znajduje sie w bazie
- bool Serwer::isRegistred(string login){
- fstream File;
- size_t pos;
- File.open("users.db", std::ios::in);
- if( !File.good())
- {
- fstream("users.db", ios::out).close();
- File.open("users.db", std::ios::in);
- }
- string temp,username,password;
- while(!File.eof()){
- getline(File, temp);
- if(temp.length() != 0){
- pos = temp.find("?");
- if(pos != 0){
- username = temp.substr(0, pos);
- if(username == login){
- File.close();
- return true;
- }
- }
- }
- }
- File.close();
- return false;
- }
- //Funkcja zapisuje do pliku dane o uzytkowniku
- void Serwer::Register(string login, string pass){
- fstream File;
- File.open("users.db", std::ios::out | ios::app);
- string temp;
- temp = login;
- temp += "?";
- temp += pass;
- temp += "\n";
- File << temp;
- File.close();
- }
- // gruba funkcja odpowiedzialna za dekodowanie METOD i wykonanie odpowiednich działań z nimi związanych
- bool Serwer::decodeMethod(int method, SOCKET *clientSocket)
- {
- switch (method)
- {
- case 1: // rejestracja
- {
- if (logIn == false)
- {
- string tmp = packetIN.Payload;
- int delimeterPos = tmp.find('?');
- string tmpLogin = tmp.substr(0, delimeterPos);
- string tmpPass = tmp.substr(delimeterPos+1, tmp.length());
- generatePacket(packetOUT, 5, "", "Pomyslnie zarejestrowano uzytkownika");
- if(isRegistred(tmpLogin)){
- cout << "Wiadomosc systemowa: Klient o podanej nazwie istnieje juz w bazie danych!" << endl;
- generatePacket(packetOUT, 6, "", "Uzytkownik o tej nazwie istnieje juz w bazie danych!");
- }else{
- if ((tmpLogin.length() > 2) && (tmpPass.length() > 2))
- {
- // w naszym przypadku moze być tylko jeden zarejestrowany uzytkownik (można rozbudować)
- // w takim układzie dane są nadpisywane i nie jest sprawdzane, czy użytkownik o takim loginie istnieje
- strcpy(userName, tmpLogin.c_str());
- strcpy(userPw, tmpPass.c_str());
- Register(tmpLogin.c_str(), tmpPass.c_str());
- cout << "Wiadomosc systemowa: Klient zarejestowal sie(" << userName << ")" << endl;
- generatePacket(packetOUT, 5, "", "Pomyslnie zarejestrowano uzytkownika");
- }
- else
- {
- cout << "Wiadomosc systemowa: Klient podal niepoprawne dane! Rejestracja nie powiodla sie" << endl;
- generatePacket(packetOUT, 6, "", "Login lub haslo jest nieprawidlowy (minimum 3 znaki)!");
- }
- }
- }
- else
- {
- cout << "Wiadomosc systemowa: Klient probowal utworzyc konto (jest zalogowany!)" << endl;
- generatePacket(packetOUT, 6, userKey, "Nie mozesz zarejestrowac konta jako zalogowany uzytkownik!");
- }
- sendMsg(clientSocket);
- break;
- }
- case 2: // logowanie
- {
- if (logIn == false)
- {
- string tmp = packetIN.Payload;
- int delimeterPos = tmp.find('?');
- string tmpLogin = tmp.substr(0, delimeterPos);
- string tmpPass = tmp.substr(delimeterPos+1, tmp.length());
- // warto wprowadzić obsługę sprawdzania danych z tymi z pliku
- if (login(tmpLogin, tmpPass))
- {
- strcpy(userName, tmpLogin.c_str());
- logIn = true;
- int temp;
- srand(unsigned(time(NULL)));
- strcpy(userKey, "");
- for(int i = 0 ; i < 7 ; i++){
- temp = rand()%2;
- if(temp){
- userKey[i] = (char)((rand()%58) + 65);
- }else{
- userKey[i] = (char)((rand()%10) + 48);
- }
- }
- userKey[7] = '\0';
- /*ostringstream randStream;
- randStream << rand()%1000;
- string tKey = randStream.str();
- strcpy(userKey, tKey.c_str());
- strcat(userKey, "ukey5");*/
- // można wymyślić coś ambitniejszego, ale po co?
- cout << "Wiadomosc systemowa: Klient zalogowal sie(" << userName << ")" << endl;
- generatePacket(packetOUT, 5, userKey, "Pomyslnie zalogowano do systemu");
- }
- else
- {
- cout << "Wiadomosc systemowa: Klient podal niepoprawne dane! Logowanie nie powiodlo sie" << endl;
- generatePacket(packetOUT, 6, "", "Login lub haslo jest nieprawidlowy!");
- }
- }
- else
- {
- cout << "Wiadomosc systemowa: Klient probowal zalogowac sie (sesja juz istnieje!)" << endl;
- generatePacket(packetOUT, 6, userKey, "Jestes juz zalogowany!");
- }
- sendMsg(clientSocket);
- break;
- }
- case 3: // wylogowywanie
- {
- if (logIn == true)
- {
- logIn = false;
- cout << "Wiadomosc systemowa: " << userName << " - wylogowal sie!" << endl;
- strcpy(userKey, "");
- strcpy(userPw, "");
- strcpy(userName, "");
- generatePacket(packetOUT, 5, "", "Poprawnie wylogowano!");
- }
- else
- {
- cout << "Wiadomosc systemowa: Klient probowal sie wylogowac (sesja nie istnieje!)" << endl;
- generatePacket(packetOUT, 6, "", "Nie jestes zalogowany!");
- }
- sendMsg(clientSocket);
- break;
- }
- case 4: // wiadomość tekstowa
- {
- if (logIn == true)
- {
- if(strcmp(packetIN.Key, userKey) == 0){
- cout << "Wiadomosc systemowa: " << userName << " napisal(a): " << packetIN.Payload << endl;
- generatePacket(packetOUT, 5, userKey, "Wiadomosc odebrana na serwerze!");
- }else{
- logIn = false;
- strcpy(userKey, "");
- cout << "Wiadomosc systemowa: " << userName << " - blad sesji" << endl;
- generatePacket(packetOUT, 6, "", "Identyfikator sesji jest niepoprawny! Zaloguj sie ponownie!");
- }
- }
- else
- {
- cout << "Wiadomosc systemowa: Klient wyslal wiadomosc tekstowa, ale nie jest zalogowany!" << endl;
- generatePacket(packetOUT, 6, "", "Nie jestes zalogowany!");
- }
- sendMsg(clientSocket);
- break;
- }
- case 5: // OK
- {
- cout << "Operacja wykonana pomyslnie!" << endl << "Tresc komunikatu: " << packetIN.Payload << endl;
- break;
- }
- case 6: // Błąd
- {
- cout << "Wystapil blad!" << endl << "Tresc komunikatu: " << packetIN.Payload << endl;
- break;
- }
- case 7: // Rozłączenie
- {
- if (isClientActive)
- {
- cout << "Wiadomosc systemowa: Klient rozlaczyl sie" << endl;
- generatePacket(packetOUT, 5, "", "Rozlaczono!");
- sendMsg(clientSocket);
- disconnect(clientSocket);
- }
- else
- cout << "Wiadomosc systemowa: Klient probowal sie rozlaczyc (polaczenie nie istnieje!)" << endl;
- break;
- }
- default: return false;
- }
- return true;
- }
- void Serwer::showPacket(packet pack){
- cout << pack.Identifier << endl;
- cout << pack.Method << endl;
- cout << pack.Expires << endl;
- cout << pack.Key << endl;
- cout << pack.payloadLength << endl;
- cout << pack.Payload << endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement