Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // UDPConnection.cpp : Defines the entry point for the console application.
- #include "stdafx.h"
- #include <iostream>
- #include <stdlib.h>
- #include <winsock.h>
- #include <bitset>
- #include <limits.h>
- #include <vector>
- #include <algorithm>
- #include <time.h>
- #include <math.h>
- #pragma comment(lib, "Ws2_32.lib")
- #define SERVERPORT 4950
- /*
- operacje
- 00 - dodawanie
- 01 - mnozenie
- 10 - odejmowanie
- 11 - dzielenie
- status
- 0000 - popros ID
- 0001 - ID wyslane
- 0010 - zadanie obliczenia
- 0011 - zwrocenie wyniku obliczenia
- 0100 - zadanie sumy wielu liczb lub przeslanie kolejnych liczb do sumowania
- 0101 - ostatnie liczby do sumowania
- 0110 - blad
- 0111-1111 - niezdefiniowane
- */
- class Packet {
- int operation; //bity 0-1
- int number1; //bity 2-64
- int number2; //bity 2-64
- int number3; //bity 2-64
- int status; //bity 65-69
- int id; //bity 70-73
- int sizeNumber1; //bity 74-78
- int sizeNumber2; //bity 79-83
- int sizeNumber3; //bity 84-88
- std::bitset<89> binaryData; //pakiet zapisany w formacie binarnym
- unsigned char packet[12]; //pakiet w formie do przeslania
- public:
- Packet() {
- operation = 0;
- number1 = 0;
- number2 = 0;
- number3 = 0;
- status = 0;
- id = 0;
- sizeNumber1 = 0;
- sizeNumber2 = 0;
- sizeNumber3 = 0;
- for (int i = 0; i < 12; i++)packet[i] = 0; //wyzerowanie pakietu
- }
- private:
- //obliczanie wielkosci liczby w bitach
- int bitSize(int number) {
- int size = 0;
- while (number >= 1) {
- ++size;
- number /= 2;
- }
- return size;
- }
- //zamiana liczb na postac binarna i wstawienie ich do bitset
- void setBits(int number, int startingBit, int size) {
- std::vector<int> binary;
- while (number >= 1) {
- binary.push_back(number % 2);
- number /= 2;
- }
- while (binary.size() < size)binary.push_back(0); //dodaj przednie 0
- std::reverse(binary.begin(), binary.end()); //odwroc bityaby otrzymac poprawna liczbe binarna
- for (int i = 0; i < binary.size(); i++) {
- binaryData[startingBit + i] = binary[i];
- if (startingBit == binaryData.size() - 1)break; //jezeli to ostatni bit pakietu, przerwij petle
- }
- }
- //zamiana z postaci binarnej na dziesietna
- void decodeBits(int &number, int startingBit, int size) {
- int power = size - 1;
- int currentBit = startingBit;
- number = 0;
- for (int i = 0; i < size; i++) {
- if (binaryData[currentBit] == 1)
- number += pow(2, power - i);
- currentBit++;
- }
- }
- //zapisanie jednej z 3 liczb do pakietu
- bool chooseNumber(int number, int value) {
- switch (number) {
- case 1:
- if (number <= INT_MAX) {
- this->number1 = value;
- this->sizeNumber1 = bitSize(value);
- return true;
- }
- else return false;
- break;
- case 2:
- if (number <= INT_MAX)
- {
- this->number2 = value;
- this->sizeNumber2 = bitSize(value);
- return true;
- }
- else return false;
- break;
- case 3:
- if (number <= INT_MAX && (this->sizeNumber1 + this->sizeNumber2 + bitSize(value)) < 62) {
- this->number3 = value;
- this->sizeNumber3 = bitSize(value);
- return true;
- }
- else return false;
- break;
- }
- }
- //tworzenie pakietu do wyslania z reprezentajci binarnej
- void packThePacket() {
- for (int i = 0; i < 12; i++)packet[i] = 0;
- int currentPart = 0, bitValue = 0, bitCounter = 0, power = 7;
- for (int i = 0; i < binaryData.size(); i++) {
- bitValue = binaryData[i];
- if (bitValue == 1)packet[currentPart] += pow(2, power);
- power--;
- bitCounter++;
- if (bitCounter == 8) {
- bitCounter = 0;
- currentPart++;
- power = 7;
- }
- }
- }
- void unpackThePacket() {
- for (int i = 0; i < 12; i++) setBits(packet[i], i * 8, 8);
- }
- public:
- //tworzenie pakietu, zamiana z postaci dziesietnej na postac binarna wartosci pakietu oraz pakowanie do wyslania
- void createPacket() {
- setBits(operation, 0, 2); //bity 0-1
- setBits(number1, 2, sizeNumber1); //bity 2-64
- setBits(number2, 2 + sizeNumber1, sizeNumber2); //bity 2-64
- setBits(number3, 2 + sizeNumber1 + sizeNumber2, sizeNumber3); //bity 2-64
- setBits(status, 65, 4); //bity 65-69
- setBits(id, 70, 4); //bity 70-73
- setBits(sizeNumber1, 74, 5); //bity 74-78
- setBits(sizeNumber2, 79, 5); //bity 79-83
- setBits(sizeNumber3, 84, 5); //bity 84-88
- packThePacket();
- }
- void decodePacket(unsigned char* packet) {
- setPacket(packet); //wczytanie przeslanego pakietu
- unpackThePacket(); //rozpakowanie pakietu do postaci binarnej
- //zamiana wartosci binarnej na wartosci dziesietne
- decodeBits(operation, 0, 2); //bity 0-1
- decodeBits(sizeNumber1, 74, 5); //bity 74-78
- decodeBits(sizeNumber2, 79, 5); //bity 79-83
- decodeBits(sizeNumber3, 84, 5); //bity 84-88
- decodeBits(number1, 2, sizeNumber1); //bity 2-64
- decodeBits(number2, 2 + sizeNumber1, sizeNumber2); //bity 2-64
- decodeBits(number3, 2 + sizeNumber1 + sizeNumber2, sizeNumber3); //bity 2-64
- decodeBits(status, 65, 4); //bity 65-69
- decodeBits(id, 70, 4); //bity 70-73
- }
- void inputData(int operation) {
- int value;
- if (operation <= 4) {
- std::cout << "Podaj 1 liczbe: ";
- do {
- std::cin >> value;
- } while (!chooseNumber(1, value));
- std::cout << "Podaj 2 liczbe: ";
- do {
- std::cin >> value;
- } while (!chooseNumber(2, value));
- std::cout << "Podaj 3 liczbe: ";
- do {
- std::cin >> value;
- } while (!chooseNumber(3, value));
- }
- else {
- std::cout << "Nieoczekiwany blad programu!" << std::endl;
- }
- if (operation <= 3) {
- this->operation = operation; //operacja jaka serwer ma wykoac z liczbami
- status = 2; //wyslanie danych do obliczenia przez serwer
- }
- else if (operation == 4) {
- this->operation == 0; //operacja - sumowanie
- char last;
- do {
- std::cout << "Czy to ostatnie liczby? t/n: ";
- std::cin >> last;
- } while (last != 't' && last != 'n');
- if (last == 't')status = 5; //wyslij serwerowi informacje ze to ostatnia liczba
- else status = 4; //wyslij informacje serwerowi ze beda przesylane liczby
- }
- createPacket();
- }
- //zapisanie przyslanego pakietu
- void setPacket(unsigned char* packet) {
- for (int i = 0; i < 12; i++)this->packet[i] = packet[i];
- }
- //zwrocenie pakietu do przeslania
- void getPacket(unsigned char* packet) {
- for (int i = 0; i < 12; i++)packet[i] = this->packet[i];
- }
- std::bitset<89> getBinaryData() {
- return this->binaryData;
- }
- void setId(int id) {
- this->id = id;
- }
- int getOperation() {
- return this->operation;
- }
- int getStatus() {
- return this->status;
- }
- int getId() {
- return this->id;
- }
- int getProduct() {
- return this->number1;
- }
- void showStructure() {
- std::cout << operation << " " << number1 << " " << number2 << " " << number3 << " " << status << " " << id << " " << sizeNumber1 << " " << sizeNumber2 << " " << sizeNumber3 << std::endl;
- }
- void showPacket() {
- for (int i = 0; i < binaryData.size(); i++) {
- std::cout << binaryData[i];
- if (i != 0 && i % 8 == 0) std::cout << " ";
- }
- std::cout << std::endl;
- }
- };
- class Connection {
- int CLIENTPORT;
- sockaddr_in client;
- sockaddr_in server;
- WSADATA wsaData;
- SOCKET mainSocket;
- int bytesSent;
- int bytesRecv = -1;
- Packet packet;
- unsigned char packetRecived[12];
- unsigned char packetSent[12];
- public:
- Connection() {
- CLIENTPORT = rand() % 1000 + 5000;
- memset(&client, 0, sizeof(client));
- client.sin_family = AF_INET;
- client.sin_addr.s_addr = inet_addr("127.0.0.1");
- client.sin_port = htons(CLIENTPORT);
- memset(&server, 0, sizeof(server));
- server.sin_family = AF_INET;
- server.sin_addr.s_addr = inet_addr("127.0.0.1");
- server.sin_port = htons(SERVERPORT);
- }
- bool connect() {
- int result = WSAStartup(MAKEWORD(2, 2), &wsaData); //wybor wersji winsock
- if (result != NO_ERROR)
- std::cout << "Blad inicjalizacji" << std::endl;
- mainSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //tworzenie socketu UDP
- if (mainSocket == INVALID_SOCKET)
- {
- std::cout << "Blad podczas tworzenia socketu: " << WSAGetLastError() << std::endl;
- WSACleanup();
- return 0;
- }
- //przypisanie socketu do adresu
- if (bind(mainSocket, (SOCKADDR *)& client, sizeof(client)) == SOCKET_ERROR)
- {
- std::cout << "bind() zakonczony niepoowdzeniem " << std::endl;
- closesocket(mainSocket);
- return 0;
- }
- }
- void requestId() {
- //Wyslij poczatkowy pakiet proszacy o id
- for (int i = 0; i < 12; i++)packetSent[i] = 0;
- bytesSent = sendto(mainSocket, (char*)packetSent, sizeof(packetSent), 0,
- (struct sockaddr *) & server, sizeof(struct sockaddr));
- }
- void sendData() {
- int operation;
- std::cout << "Jaka operacje chcesz wykonac? \n0.Dodawanie \n1.Mnozenie \n2.Odejmowanie \n3.Dzielenie \n4.Suma wielu liczb\n";
- do {
- std::cin >> operation;
- } while (operation<0 || operation>4);
- packet.inputData(operation);
- packet.getPacket(packetSent);
- bytesSent = sendto(mainSocket, (char *)packetSent, sizeof(packetSent), 0,
- (struct sockaddr *) & server, sizeof(struct sockaddr));
- //jezeli wybrano opcje sumowania wielu liczb i nie sa to ostatnie liczby
- while (operation == 4 && packet.getStatus() == 4) {
- packet.inputData(operation);
- packet.getPacket(packetSent);
- bytesSent = sendto(mainSocket, (char *)packetSent, sizeof(packetSent), 0,
- (struct sockaddr *) & server, sizeof(struct sockaddr));
- }
- }
- void reciveData(){
- int addr_len = sizeof(struct sockaddr);
- bytesRecv = recvfrom(mainSocket, (char *)&packetRecived, sizeof(packetRecived), 0,
- (struct sockaddr *) & client, &addr_len);
- packet.decodePacket(packetRecived);
- int status = packet.getStatus();
- switch (status) {
- case 1: //nadanie id
- std::cout << "Otrzymano id: " << packet.getId() << std::endl;
- break;
- case 3: //odebranie wyniku dzialania arytmetycznego
- std::cout << "Wynik dzialania: " << packet.getProduct() << std::endl; //serwer zawsze zwraca wynik w 1 liczie
- break;
- case 6: //blad
- std::cout << "Blad!" << std::endl;
- default: //nieokreslone
- std::cout << "Nieokreslone" << std::endl;
- break;
- }
- }
- };
- int main(void)
- {
- srand(time(NULL));
- Connection connection;
- connection.connect();
- connection.requestId();
- while (true) {
- connection.reciveData();
- connection.sendData();
- }
- system("PAUSE");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement