Advertisement
Guest User

Untitled

a guest
Nov 22nd, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.52 KB | None | 0 0
  1. //Server
  2. #pragma comment(lib,"ws2_32.lib")
  3. #include <WS2tcpip.h>
  4. #include <iostream>
  5. #include <bitset>
  6. #include <sstream>
  7. #include  <string>
  8. #include <vector>
  9.  
  10. int convertBinaryToDecimal(long long n)
  11. {
  12.     int decimalNumber = 0, i = 0, remainder;
  13.     while (n != 0)
  14.     {
  15.         remainder = n % 10;
  16.         n /= 10;
  17.         decimalNumber += remainder*pow(2, i);
  18.         ++i;
  19.     }
  20.     return decimalNumber;
  21. }
  22. // Done ale brzydko V
  23. std::string zamianaBND(std::string x)
  24. {
  25.     int n = stoi(x);
  26.     n = convertBinaryToDecimal(n);
  27.     x = std::to_string(n);
  28.     return x;
  29. }
  30. //DoneVVV
  31. std::string zamianaDNB(std::string x)
  32. {
  33.     int number = stoi(x);
  34.  
  35.     std::bitset<16> mySet(number);
  36.     x = mySet.to_string();
  37.     x.erase(0, min(x.find_first_not_of('0'), x.size() - 1));
  38.     return x;
  39. }
  40. //Z tego jestem tak dumny V xd
  41. std::string zamianaSNB(std::string x) //string
  42. {
  43.     std::string wynik;
  44.  
  45.     for (std::size_t i = 0; i < x.size(); ++i)
  46.     {
  47.         std::stringstream stream;
  48.         stream << std::bitset<8>(x[i]);
  49.         wynik += stream.str();
  50.  
  51.     }
  52.  
  53.     return wynik;
  54. }
  55.  
  56. std::string zamianaBNS(std::string data)
  57. {
  58.     std::stringstream sstream(data);
  59.     std::string output;
  60.     while (sstream.good())
  61.     {
  62.         std::bitset<8> bits;
  63.         sstream >> bits;
  64.         char c = char(bits.to_ulong());
  65.         output += c;
  66.     }
  67.  
  68.     return output;
  69. }
  70.  
  71. std::string encodeBitsToBaits(std::string inputDatagramInBits)
  72. {
  73.     // Dopelnienie zerami, jesli jest taka potrzeba
  74.     while (inputDatagramInBits.size() % 8 != 0)
  75.     {
  76.         inputDatagramInBits.push_back('0');
  77.     }
  78.  
  79.     // Po uzupelnieniu pakiet jest gotowy do zamiany na bajty
  80.  
  81.     int datagramLength = inputDatagramInBits.size();
  82.  
  83.     char bait = 0; // Zmienna bait bedzie zapisywala kolejne osemki bitow
  84.     std::string datagramInBaits; // PakietBajtow to gotowy lancuch bajtow
  85.     int operationIndex = 0; // Zmienna OperationIndeks jest niezbedna przy operacjach na bitach
  86.  
  87.                             // Zmienna i wskazuje na pierwszy bit z danej osemki bitow
  88.     for (int i = 0; i < datagramLength; i += 8)
  89.     {
  90.         bait = 0;
  91.         operationIndex = 0;
  92.  
  93.         // Zmienna j iteruje po osmiu kolejnych bitach zaczynajac od bitu i. Jesli bit jest jedynka, to jedynka zostaje przesunieta na odpowiednia pozycje
  94.         for (int j = i; j < i + 8; ++j)
  95.         {
  96.             if (inputDatagramInBits[j] == '1')
  97.             {
  98.                 bait = bait | 1 << (7 - operationIndex);
  99.             }
  100.             operationIndex++;
  101.         }
  102.  
  103.         // Dopisanie gotowego bajtu danych do zmiennej datagramInBaits
  104.         datagramInBaits.push_back(bait);
  105.     }
  106.  
  107.     // Zwrocenie datagramu, w ktorym kazdy znak zapisuje 8 bitow
  108.     return datagramInBaits;
  109. }
  110.  
  111. std::string decodeBaitsToBits(std::string inputDatagramInBaits)
  112. {
  113.     std::string datagramInBits;
  114.     std::string bits;
  115.     // Zmienna i iteruje po kolejnych bajtach az do konca lancucha znakow
  116.     for (int i = 0; i < inputDatagramInBaits.size(); i++)
  117.     {
  118.         bits.clear();
  119.         // Zapisanie danego znaku jako liczby i zapisanie tej liczby do bitset
  120.         int charAsInteger = inputDatagramInBaits[i];
  121.         std::bitset<8> mySet(charAsInteger);
  122.  
  123.         // Zapisanie danego bajtu jako ciagu zer i jedynek o dlugosci 8 do zmiennej bits
  124.         bits = mySet.to_string();
  125.  
  126.         //Dopisanie osmiu zer i jedynek do wynikowego datagramu
  127.         datagramInBits += bits;
  128.     }
  129.  
  130.     //Zwrocenie datagramu, w ktorym kazdy znak ma wartosc 1 lub 0
  131.     return datagramInBits;
  132. }
  133.  
  134. std::string poprawnyOdbior(char input[4096])
  135. {
  136.     std::string temp;
  137.     std::string odpowiedz;
  138.     std::string rozmiarBin;
  139.     std::string jedynaslusznaodpowiedz;
  140.     int rozmiarDec;
  141.     int rozmiarCalegoPakietuWBajtach;
  142.     for (int i = 0; i < 9; i++)
  143.     {
  144.         temp += input[i];
  145.     }
  146.  
  147.     temp = decodeBaitsToBits(temp);
  148.     for (int i = 5; i <= 68; i++)
  149.     {
  150.         rozmiarBin += temp[i];
  151.     }
  152.  
  153.     rozmiarDec = stoi(zamianaBND(rozmiarBin));
  154.  
  155.     rozmiarCalegoPakietuWBajtach = ((68 + rozmiarDec) / 8);
  156.  
  157.     if (((68 + rozmiarDec)%8) > 0) rozmiarCalegoPakietuWBajtach += 1;
  158.  
  159.     for (int i = 0; i < rozmiarCalegoPakietuWBajtach; i++)
  160.     {
  161.         odpowiedz += input[i];
  162.     }
  163.  
  164.     jedynaslusznaodpowiedz = decodeBaitsToBits(odpowiedz);
  165.  
  166.     while (jedynaslusznaodpowiedz.size() > (69 + rozmiarDec))
  167.     {
  168.         jedynaslusznaodpowiedz.pop_back();
  169.     }
  170.  
  171.     return jedynaslusznaodpowiedz;
  172. }
  173.  
  174. void prepare(std::string &buff, std::string toSend)
  175. {
  176.     buff.erase(buff.begin() + 77, buff.end()); // wywalamy stare dane
  177.  
  178.  
  179.     int number = toSend.size() ;
  180.     std::string rozmiar;
  181.     std::bitset<64> mySet(number + 8);
  182.     rozmiar = mySet.to_string(); // tu ustawiamy pole dlugosci danych w 64 bitach
  183.  
  184.     for (int i = 0; i < 64; ++i) {
  185.         buff[5 + i] = rozmiar[i];  // zapisujemy ten rozmiar w pliku
  186.     }
  187.  
  188.     for (int i = 0; i < number; ++i) // zapisujemy dane do wyslania
  189.     {
  190.         buff.push_back(toSend[i]);
  191.     } //tu zapisuje dane na ich polu
  192.  
  193.     std::string temporary = encodeBitsToBaits(buff);
  194.     buff = temporary;
  195. }
  196.  
  197. void prepare1(std::string &buff, std::string toSend)
  198. {
  199.     //buff.erase(buff.begin() + 75, buff.end()); // wywalamy stare dane
  200.  
  201.  
  202.     int number = toSend.size();
  203.     std::string rozmiar;
  204.     std::bitset<64> mySet(number);
  205.     rozmiar = mySet.to_string(); // tu ustawiamy pole dlugosci danych w 64 bitach
  206.  
  207.     for (int i = 0; i < 64; ++i) {
  208.         buff[5 + i] = rozmiar[i];  // zapisujemy ten rozmiar w pliku
  209.     }
  210.  
  211.     for (int i = 0; i < number; ++i) // zapisujemy dane do wyslania
  212.     {
  213.         buff.push_back(toSend[i]);
  214.     } //tu zapisuje dane na ich polu
  215.  
  216.     std::string temporary = encodeBitsToBaits(buff);
  217.     buff = temporary;
  218. }
  219.  
  220. // Obliczanie silni. Jesli zakres zostanie przekroczony, funkcja zapisuje w isError wartosc 2
  221. int silnia(int x, int &isError)
  222. {
  223.     int potega = 1;
  224.     for (int i = 1; i <= x; i++) {
  225.         potega *= i;
  226.         if (potega < 0)
  227.         {
  228.             isError = 2;
  229.             return 0;
  230.         }
  231.     }
  232.     return potega;
  233. }
  234.  
  235. void main()
  236. {
  237.     // Initialize Winsock
  238.     WSAData wsaData;
  239.     WORD DllVersion = MAKEWORD(2, 1);
  240.     if (WSAStartup(DllVersion, &wsaData) != 0)
  241.     {
  242.         std::cout << "Nie mozna uruchomic Winsock" << std::endl;
  243.         return;
  244.     }
  245.  
  246.     // Create socket
  247.     SOCKET listening = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //odpowiedzialny za nasluchiwanie(address family that is used to designate the type of addresses that your socket can communicate with (in this case, Internet Protocol v4 addresses), (TCP))
  248.     if (listening == INVALID_SOCKET)
  249.     {
  250.         std::cout << "Nie mozna stworzyc Wincosk" << std::endl;
  251.         return;
  252.     }
  253.  
  254.     // Bind the ip address and port to a socket
  255.     sockaddr_in hint;
  256.     hint.sin_family = AF_INET;//IPv4
  257.     hint.sin_port = htons(8888);//host to network short - rozwiazuje problemy z big i little indian, port
  258.     hint.sin_addr.s_addr = INADDR_ANY; //tu idzie adres IP
  259.  
  260.     bind(listening, (sockaddr*)&hint, sizeof(hint));
  261.  
  262.  
  263.     // Wait for a connection
  264.     sockaddr_in client;
  265.     int clientSize = sizeof(client);
  266.  
  267.     //SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize); //jakie polaczenia akceptujemy
  268.  
  269.  
  270.  
  271.     // Close listening socket
  272.     // closesocket(listening);
  273.  
  274.     // While loop: accept and echo message back to client
  275.     char buff[4096];//rozmiar bufora
  276.     int sesja = 0;
  277.     struct wpis
  278.     {
  279.         int nrSesji;
  280.         std::string operacja;
  281.     };
  282.     std::vector<wpis> historia;
  283.  
  284.     std::string stringSesji;    // ================================== dodalem string sesji
  285.  
  286.     while (true)
  287.     {
  288.         ZeroMemory(buff, 4096);
  289.  
  290.         // Wait for client to send data
  291.         int bytesRecieved = recvfrom(listening, buff, 4096, 0, (struct sockaddr *) &client, &clientSize); //rozmiar danych otrzymanych na serwerze
  292.  
  293.         std::string odebraneDane = poprawnyOdbior(buff);
  294.  
  295.         std::cout << bytesRecieved << std::endl;
  296.         if (bytesRecieved == SOCKET_ERROR)
  297.         {
  298.             std::cout << "Error in recv(). Quitting" << std::endl;
  299.             continue;
  300.         }
  301.  
  302.         if (bytesRecieved == 0)
  303.         {
  304.             std::cout << "Client disconnected " << std::endl;
  305.             continue;
  306.         }
  307.         // S T A R T
  308.         int wynik;
  309.  
  310.         std::string number = odebraneDane; //hehe (getit string a to numer xD xD xD dobre bardzo)
  311.                                   // 4 - 67
  312.         std::string dane; // tu sobie je na dziesietne zrobie bo moge
  313.         for (int i = 5; i < 69; i++)
  314.         {
  315.             dane.push_back(number[i]);
  316.         }
  317.  
  318.         dane = zamianaBND(dane);
  319.  
  320.         int rozmiarDanych = stoi(dane);
  321.         dane = "";
  322.         //if (rozmiarDanych)
  323.         //{
  324.  
  325.         //  for (int i = 0; i < rozmiarDanych - 8; i++)
  326.         //  {
  327.         //      dane += number[77 + i];
  328.         //  }
  329.         //  dane = zamianaBNS(dane);
  330.         //  rozmiarDanych = dane.size() - 1; // znak konca sie tez zalicza przez te glupie chary
  331.         //}
  332.  
  333.         // Operacja 00 - polaczenie
  334.         if (number[0] == '0' && number[1] == '0')
  335.         {
  336.             // Status 000 - pierwsze polaczenie, zadanie przydzielenia numeru sesji
  337.             if (number[2] == '0' && number[3] == '0' && number[4] == '0')
  338.             {
  339.                 sesja++;
  340.                 std::string old_string = std::to_string(sesja);
  341.                 old_string = zamianaDNB(old_string);
  342.                 std::string new_string = std::string(6 - old_string.length(), '0') + old_string; // z 1 robi 00000001 etc
  343.  
  344.                 std::string daneDoWyslania;
  345.  
  346.                 for (int i = 0; i < new_string.length(); i++)
  347.                 {
  348.                     daneDoWyslania.push_back(new_string[i]);
  349.                 }
  350.                 number[2] = '1';
  351.                 number[3] = '0';
  352.                 number[4] = '1';
  353.  
  354.                 stringSesji = daneDoWyslania; // ================================================== zapisuje numer sesji w string sesji
  355.  
  356.                 prepare1(number, daneDoWyslania);
  357.                 sendto(listening, number.c_str(), number.size() + 1, 0, (struct sockaddr *) &client, clientSize);
  358.             }
  359.             if (number[2] == '1' && number[3] == '1' && number[4] == '1')
  360.             {
  361.                 std::cout << "Odebrano operacje 00 o statusie 111 - klient zakonczyl polaczenie." << std::endl;
  362.                 continue;
  363.             }
  364.         }
  365.         //Operacja 01 - silnia
  366.         else if (number[0] == '0' && number[1] == '1')
  367.         {
  368.             for (int i = 0; i < rozmiarDanych - 6; i++)
  369.             {
  370.                 dane += number[75 + i];
  371.             }
  372.             dane = zamianaBNS(dane);
  373.             rozmiarDanych = dane.size() - 1; // znak konca sie tez zalicza przez te glupie chary
  374.  
  375.             int isError = 0; // Zmienna okreslajaca blad w dzialaniach: 0 - OK, 1 - Blad Klienta, 2 - overflow
  376.             std::string a;
  377.             for (int i = 0; i < rozmiarDanych; i++)
  378.             {
  379.                 a.push_back(dane[i]);
  380.             }
  381.  
  382.             // Obliczenie silni dla podanej liczby
  383.             int b = stoi(a);
  384.             wynik = silnia(b, isError);
  385.  
  386.             // Zapisanie wyniku dzialania do historii obliczen
  387.             wpis tmp;
  388.             tmp.nrSesji = sesja;
  389.             tmp.operacja = "Silnia z " + a + " wynosi " + std::to_string(wynik);
  390.             historia.push_back(tmp);
  391.            
  392.             std::string toSend;
  393.  
  394.             if (isError == 0)
  395.             {
  396.                 // Przygotowanie danych do wyslania
  397.                 toSend = std::to_string(wynik);
  398.                 toSend = zamianaDNB(toSend);
  399.            
  400.                 //Ustawienie statusu na 101 - prawidlowa odpowiedz
  401.                 number[2] = '1';
  402.                 number[3] = '0';
  403.                 number[4] = '1';
  404.                 prepare(number, toSend);
  405.             }
  406.             else if (isError == 1)
  407.             {
  408.                 // Przygotowanie danych do wyslania
  409.                 toSend = "";
  410.                 toSend = zamianaDNB(toSend);
  411.  
  412.                 //Ustawienie statusu na 001 - blad po stronie klienta
  413.                 number[2] = '0';
  414.                 number[3] = '0';
  415.                 number[4] = '1';
  416.                 prepare(number, toSend);
  417.             }
  418.             else if (isError == 2)
  419.             {
  420.                 // Przygotowanie danych do wyslania
  421.                 toSend = "";
  422.                 toSend = zamianaDNB(toSend);
  423.  
  424.                 //Ustawienie statusu na 100 - przekroczenie zakresu zmiennej
  425.                 number[2] = '1';
  426.                 number[3] = '0';
  427.                 number[4] = '0';
  428.                 prepare(number, toSend);
  429.             }
  430.             else { std::cout << "Nieznany blad serwera" << std::endl; }
  431.            
  432.  
  433.             //Odeslanie wyniku dzialania/bledu do klienta
  434.             sendto(listening, number.c_str(), number.size() + 1, 0, (struct sockaddr *) &client, clientSize);
  435.         }
  436.    
  437.         // Operacja 10 - dzialanie na 2 argumentach
  438.         else if(number[1] == '0' && number[0] == '1')
  439.         {
  440.             for (int i = 0; i < rozmiarDanych - 8; i++)
  441.             {
  442.                 dane += number[77 + i];
  443.             }
  444.             dane = zamianaBNS(dane);
  445.             rozmiarDanych = dane.size() - 1; // znak konca sie tez zalicza przez te glupie chary
  446.  
  447.             // Status 110 - zadanie klienta
  448.             if (number[2] == '1' && number[3] == '1' && number[4] == '0')
  449.             {
  450.                 int isError = 0; // Zmienna okreslajaca blad w dzialaniach: 0 - OK, 1 - Blad Klienta, 2 - overflow
  451.  
  452.                 if (number.size() < 79) {
  453.                     isError = 1;
  454.                     std::cout << "Blad klienta";
  455.                 }
  456.  
  457.                 // Dzialanie 00 - mnozenie 2 liczb
  458.                 if (number[75] == '0' && number[76] == '0')
  459.                 {
  460.                     std::string a, b;
  461.                     int ktory = 0;
  462.  
  463.                     // Podzial danych na liczby a i b oddzielone spacja
  464.                     for (int i = 0; i < rozmiarDanych; i++)
  465.                     {
  466.                         if (ktory == 0)
  467.                         {
  468.                             if (dane[i] != ' ') { a.push_back(dane[i]); }
  469.                             else { ktory++; }
  470.                         }
  471.                         else { b.push_back(dane[i]); }
  472.                     }
  473.  
  474.                     // Obliczenie wyniku
  475.                     wynik = stoi(a) * stoi(b);
  476.  
  477.                     // Sprawdzenie, czy nie przekroczono zakresu zmiennej
  478.                     if (stoi(a) != 0 && wynik / stoi(a) != stoi(b)) {
  479.                         isError = 2;
  480.                     }
  481.  
  482.                     //Wpisanie dzialania do historii
  483.                     wpis tmp;
  484.                     tmp.nrSesji = sesja;
  485.                     tmp.operacja = a + " * " + b + " = " + std::to_string(wynik);
  486.                     historia.push_back(tmp);
  487.                 }
  488.  
  489.                 // Dzialanie 01 - dzielenie 2 liczb
  490.                 if (number[75] == '0' && number[76] == '1')
  491.                 {
  492.                     std::string a, b;
  493.                     int ktory = 0;
  494.  
  495.                     // Podzial danych na liczby a i b oddzielone spacja
  496.                     for (int i = 0; i < rozmiarDanych; i++)
  497.                     {
  498.                         if (ktory == 0)
  499.                         {
  500.                             if (dane[i] != ' ') { a.push_back(dane[i]); }
  501.                             else { ktory++; }
  502.                         }
  503.                         else { b.push_back(dane[i]); }
  504.                     }
  505.  
  506.                     wynik = stoi(a) / stoi(b);
  507.                     wpis tmp;
  508.                     tmp.nrSesji = sesja;
  509.                     tmp.operacja = a + " / " + b + " = " + std::to_string(wynik);
  510.                     historia.push_back(tmp);
  511.  
  512.                 }
  513.                 // Dzialanie 10 - dodawanie 2 liczb
  514.                 if (number[75] == '1' && number[76] == '0')
  515.                 {
  516.                     std::string a, b;
  517.                     int ktory = 0;
  518.  
  519.                     // Podzial danych na liczby a i b oddzielone spacja
  520.                     for (int i = 0; i < rozmiarDanych; i++)
  521.                     {
  522.                         if (ktory == 0)
  523.                         {
  524.                             if (dane[i] != ' ') { a.push_back(dane[i]); }
  525.                             else { ktory++; }
  526.                         }
  527.                         else { b.push_back(dane[i]); }
  528.                     }
  529.  
  530.                     // Obliczenie wyniku
  531.                     wynik = stoi(a) + stoi(b);
  532.  
  533.                     // Sprawdzenie, czy nie przekroczono zakresu zmiennej
  534.                     if (wynik - stoi(a) != stoi(b)) {
  535.                         isError = 2;
  536.                     }
  537.  
  538.                     //Wpisanie dzialania do historii
  539.                     wpis tmp;
  540.                     tmp.nrSesji = sesja;
  541.                     tmp.operacja = a + " + " + b + " = " + std::to_string(wynik);
  542.                     historia.push_back(tmp);
  543.                 }
  544.                 // Dzialanie 11 - odejmowanie 2 liczb
  545.                 if (number[75] == '1' && number[76] == '1')
  546.                 {
  547.                     std::string a, b;
  548.                     int ktory = 0;
  549.  
  550.                     // Podzial danych na liczby a i b oddzielone spacja
  551.                     for (int i = 0; i < rozmiarDanych; i++)
  552.                     {
  553.                         if (ktory == 0)
  554.                         {
  555.                             if (dane[i] != ' ') { a.push_back(dane[i]); }
  556.                             else { ktory++; }
  557.                         }
  558.                         else { b.push_back(dane[i]); }
  559.                     }
  560.  
  561.                     // Obliczenie wyniku
  562.                     wynik = stoi(a) - stoi(b);
  563.  
  564.                     // Sprawdzenie, czy nie przekroczono zakresu zmiennej
  565.                     if (wynik + stoi(b) != stoi(a)) {
  566.                         isError = 2;
  567.                     }
  568.  
  569.                     //Wpisanie dzialania do historii
  570.                     wpis tmp;
  571.                     tmp.nrSesji = sesja;
  572.                     tmp.operacja = a + " - " + b + " = " + std::to_string(wynik);
  573.                     historia.push_back(tmp);
  574.                 }
  575.  
  576.                 //Koniec dzialan - przygotowanie danych do wyslania
  577.                 std::string toSend;
  578.                 if (isError == 0)
  579.                 {
  580.                     toSend = std::to_string(wynik);
  581.                     toSend = zamianaDNB(toSend);
  582.  
  583.                     // Ustawienie statusu na 101 - poprawne zwrocenie zasobow
  584.                     number[2] = '1';
  585.                     number[3] = '0';
  586.                     number[4] = '1';
  587.  
  588.                     prepare(number, toSend);
  589.                 }
  590.                 else
  591.                 {
  592.                     toSend = "";
  593.                     // Ustawienie statusu na 010 - blad po stronie serwera
  594.                     number[2] = '0';
  595.                     number[3] = '1';
  596.                     number[4] = '0';
  597.  
  598.                     prepare(number, toSend);
  599.                 }
  600.  
  601.                 //Odeslanie wyniku dzialania/bledu do klienta
  602.                 sendto(listening, number.c_str(), number.size() + 1, 0, (struct sockaddr *) &client, clientSize);
  603.             }
  604.         }
  605.  
  606.     } // Koniec petli while(true)
  607.  
  608.       // Close
  609.     closesocket(listening);
  610.  
  611.     // Cleanup Winsock
  612.     WSACleanup();
  613.  
  614. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement