From 93e15bb77fdd28115b946eacbce308ab4a77a3c6 Mon Sep 17 00:00:00 2001 From: VadimFarutin Date: Fri, 15 Mar 2019 00:18:10 +0300 Subject: [PATCH 1/7] homework02 initial commit --- udp/server/CMakeLists.txt | 13 + udp/server/include/Currency.h | 33 +++ udp/server/include/Server.h | 52 ++++ udp/server/src/Currency.cpp | 41 +++ udp/server/src/CurrencyServerApplication.cpp | 45 ++++ udp/server/src/Server.cpp | 248 +++++++++++++++++++ 6 files changed, 432 insertions(+) create mode 100644 udp/server/CMakeLists.txt create mode 100644 udp/server/include/Currency.h create mode 100644 udp/server/include/Server.h create mode 100644 udp/server/src/Currency.cpp create mode 100644 udp/server/src/CurrencyServerApplication.cpp create mode 100644 udp/server/src/Server.cpp diff --git a/udp/server/CMakeLists.txt b/udp/server/CMakeLists.txt new file mode 100644 index 0000000..82aaa47 --- /dev/null +++ b/udp/server/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.5) +project(homework02) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_FLAGS -lpthread) + +include_directories(.) + +add_executable(homework02 + src/CurrencyServerApplication.cpp + src/Server.cpp include/Server.h + src/Currency.cpp include/Currency.h) + diff --git a/udp/server/include/Currency.h b/udp/server/include/Currency.h new file mode 100644 index 0000000..02bd819 --- /dev/null +++ b/udp/server/include/Currency.h @@ -0,0 +1,33 @@ +#ifndef CURRENCY_H +#define CURRENCY_H + +#include +#include + +class Currency { +public: + static const int32_t ABSENT_CHANGE_VALUE = -1; + + Currency(std::string name, int32_t currentRate); + + const std::string &getName() const; + + int32_t getCurrentRate() const; + + const std::vector &getRates() const; + + void addRate(int32_t rate); + + int32_t getAbsoluteChange() const; + + int32_t getRelativeChange() const; + +private: + std::string name; + std::vector rates; + int32_t absoluteChange; + int32_t relativeChange; +}; + +#endif // CURRENCY_H + diff --git a/udp/server/include/Server.h b/udp/server/include/Server.h new file mode 100644 index 0000000..03ccba8 --- /dev/null +++ b/udp/server/include/Server.h @@ -0,0 +1,52 @@ +#ifndef SERVER_H +#define SERVER_H + +#include +#include + +#include "include/Currency.h" + +class Server { +public: + Server(uint16_t portNumber); + + void start(); + + void stop() const; + +private: + void processCurrencyListQuery(); + void processNewCurrencyQuery(); + void processDeleteCurrencyQuery(); + void processAddCurrencyRateQuery(); + void processCurrencyRateHistoryQuery(); + + int32_t readCommand(); + int16_t readMessageDelimeter(); + const std::string readCurrencyName(); + int32_t readCurrencyRate(); + + int32_t readInt32(); + int16_t readInt16(); + void readChars(char *dst, size_t size); + + void sendMessageDelimeter(); + void sendString(const std::string &message, size_t len); + void sendInt32(int32_t n); + void sendInt8(int8_t n); + + void checkStatus(int n) const; + + static const int CURRENCY_NAME_SIZE = 16; + static const int BUFFER_SIZE = 508; + int8_t buffer[BUFFER_SIZE]; + int bufferPosition; + std::vector message; + std::map currencies; + + int sockfd; + uint16_t portNumber; +}; + +#endif // SERVER_H + diff --git a/udp/server/src/Currency.cpp b/udp/server/src/Currency.cpp new file mode 100644 index 0000000..d293d97 --- /dev/null +++ b/udp/server/src/Currency.cpp @@ -0,0 +1,41 @@ +#include "include/Currency.h" + +#include +#include +#include + +using namespace std; + +Currency::Currency(string name, int32_t currentRate) : name(move(name)) { + rates = {currentRate}; + absoluteChange = ABSENT_CHANGE_VALUE; + relativeChange = ABSENT_CHANGE_VALUE; +} + +const string &Currency::getName() const { + return name; +} + +int32_t Currency::getCurrentRate() const { + return rates[rates.size() - 1]; +} + +const vector &Currency::getRates() const { + return rates; +} + +void Currency::addRate(int32_t rate) { + int32_t lastRate = getCurrentRate(); + rates.push_back(rate); + absoluteChange = rate - lastRate; + relativeChange = static_cast((rate * 100.0) / lastRate); +} + +int32_t Currency::getAbsoluteChange() const { + return absoluteChange; +} + +int32_t Currency::getRelativeChange() const { + return relativeChange; +} + diff --git a/udp/server/src/CurrencyServerApplication.cpp b/udp/server/src/CurrencyServerApplication.cpp new file mode 100644 index 0000000..dc0a3f6 --- /dev/null +++ b/udp/server/src/CurrencyServerApplication.cpp @@ -0,0 +1,45 @@ +#include +#include +#include + +#include "include/Server.h" + +using namespace std; + +int main(int argc, char *argv[]) { + if (argc < 2) { + fprintf(stderr, "usage: .%s \n", argv[0]); + return 0; + } + uint16_t portNumber = static_cast(strtol(argv[1], nullptr, 10)); + + Server server(portNumber); + pthread_t serverThread; + typedef void * (*PTHREAD_FUNC_PTR)(void *); + + int rc = pthread_create(&serverThread, + nullptr, + (PTHREAD_FUNC_PTR) &Server::start, + &server); + + if (rc) { + cout << "Failed to create server." << endl; + exit(1); + } + + std::string input; + while (true) { + cin >> input; + + if (input == "q") { + server.stop(); + break; + } + } + + void *status; + pthread_join(serverThread, &status); + + return 0; +} + diff --git a/udp/server/src/Server.cpp b/udp/server/src/Server.cpp new file mode 100644 index 0000000..330fc17 --- /dev/null +++ b/udp/server/src/Server.cpp @@ -0,0 +1,248 @@ +#include "include/Server.h" + +#include +#include +#include +#include +#include +#include + +using namespace std; + +Server::Server(uint16_t portNumber) + : portNumber(portNumber) {} + +void Server::start() { + sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + if (sockfd < 0) { + perror("ERROR opening socket"); + exit(1); + } + + struct sockaddr_in serv_addr, cli_addr; + bzero((char *) &serv_addr, sizeof(serv_addr)); + + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(portNumber); + + if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { + perror("ERROR on binding"); + exit(1); + } + + unsigned int clilen = sizeof(cli_addr); + int n; + int8_t writingBuffer[BUFFER_SIZE]; + + while (true) { + bufferPosition = 0; + message.clear(); + + n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *) &cli_addr, &clilen); + + if (n < 0) { + perror("ERROR on receiving"); + continue; + } + + int32_t command = readCommand(); + + switch (command) { + case 0: + processCurrencyListQuery(); + break; + case 1: + processNewCurrencyQuery(); + break; + case 2: + processDeleteCurrencyQuery(); + break; + case 3: + processAddCurrencyRateQuery(); + break; + case 4: + processCurrencyRateHistoryQuery(); + break; + } + + int32_t dataSize = BUFFER_SIZE - 2 * sizeof(int32_t); + int32_t dGramNumber = (message.size() + dataSize - 1) / dataSize; + + for (int32_t i = 0, currentDGram = 0; i < message.size(); i += dataSize, currentDGram++) { + bzero((char *) &writingBuffer, BUFFER_SIZE); + + memcpy(writingBuffer, &dataSize, sizeof(int32_t)); + memcpy(writingBuffer + sizeof(int32_t), ¤tDGram, sizeof(int32_t)); + + for (int j = 0; j < BUFFER_SIZE && i + j < message.size(); j++) { + writingBuffer[2 * sizeof(int32_t) + j] = message[i + j]; + } + + n = sendto(sockfd, writingBuffer, BUFFER_SIZE, 0, (struct sockaddr*) &cli_addr, clilen); + + if (n < 0) { + perror("ERROR on sending"); + break; + } + } + } +} + +void Server::stop() const { + shutdown(sockfd, SHUT_RDWR); +} + +void Server::processCurrencyListQuery() { + readMessageDelimeter(); + + for (auto it = currencies.begin(); it != currencies.end(); ++it) { + Currency ¤cy = it->second; + const string &name = currency.getName(); + int32_t rate = currency.getCurrentRate(); + int32_t absoluteChange = currency.getAbsoluteChange(); + int32_t relativeChange = currency.getRelativeChange(); + int8_t hasPreviousRate = 1; + + if (relativeChange == Currency::ABSENT_CHANGE_VALUE) { + hasPreviousRate = 0; + absoluteChange = 0; + relativeChange = 0; + } + + sendString(name, CURRENCY_NAME_SIZE); + sendInt32(rate); + sendInt8(hasPreviousRate); + sendInt32(absoluteChange); + sendInt32(relativeChange); + } + + sendMessageDelimeter(); +} + +void Server::processNewCurrencyQuery() { + string name = readCurrencyName(); + int32_t rate = readCurrencyRate(); + readMessageDelimeter(); + + Currency currency = Currency(name, rate); + auto result = currencies.emplace(name, currency); + int8_t success = result.second ? 1 : 0; + + sendInt8(success); + sendMessageDelimeter(); +} + +void Server::processDeleteCurrencyQuery() { + string name = readCurrencyName(); + readMessageDelimeter(); + + int8_t success; + + if (currencies.find(name) != currencies.end()) { + success = 1; + currencies.erase(name); + } else { + success = 0; + } + + sendInt8(success); + sendMessageDelimeter(); +} + +void Server::processAddCurrencyRateQuery() { + string name = readCurrencyName(); + int32_t rate = readCurrencyRate(); + readMessageDelimeter(); + + int8_t success; + + if (currencies.find(name) != currencies.end()) { + success = 1; + Currency ¤cy = currencies.find(name)->second; + currency.addRate(rate); + } else { + success = 0; + } + + sendInt8(success); + sendMessageDelimeter(); +} + +void Server::processCurrencyRateHistoryQuery() { + string name = readCurrencyName(); + readMessageDelimeter(); + + Currency ¤cy = currencies.find(name)->second; + auto rates = currency.getRates(); + + for (auto rate : rates) { + sendInt32(rate); + } + + sendMessageDelimeter(); +} + +int32_t Server::readCommand() { + return readInt32(); +} + +int16_t Server::readMessageDelimeter() { + return readInt16(); +} + +const string Server::readCurrencyName() { + char name[CURRENCY_NAME_SIZE + 1]; + bzero(name, CURRENCY_NAME_SIZE + 1); + readChars(name, CURRENCY_NAME_SIZE); + return string(name); +} + +int32_t Server::readCurrencyRate() { + return readInt32(); +} + +int32_t Server::readInt32() { + int32_t intValue = 0; + memcpy(&intValue, buffer + bufferPosition, sizeof(intValue)); + bufferPosition += sizeof(intValue); + return intValue; +} + +int16_t Server::readInt16() { + int16_t intValue = 0; + memcpy(&intValue, buffer + bufferPosition, sizeof(intValue)); + bufferPosition += sizeof(intValue); + return intValue; +} + +void Server::readChars(char *dst, size_t size) { + memcpy(dst, buffer + bufferPosition, size); + bufferPosition += size; +} + +void Server::sendMessageDelimeter() { + sendInt8((int8_t) '\\'); + sendInt8(0); +} + +void Server::sendString(const string &src, size_t len) { + std::copy(src.begin(), src.end(), std::back_inserter(message)); + + for (int i = 0; i < len - src.size(); i++) { + message.push_back(0); + } +} + +void Server::sendInt32(int32_t d) { + message.push_back(d & 0x000000ff); + message.push_back((d & 0x0000ff00) >> 8); + message.push_back((d & 0x00ff0000) >> 16); + message.push_back((d & 0xff000000) >> 24); +} + +void Server::sendInt8(int8_t d) { + message.push_back(d); +} + From 792e25bd0f8ccdc3090e1064374b90d6a910cebb Mon Sep 17 00:00:00 2001 From: VadimFarutin Date: Fri, 15 Mar 2019 13:32:18 +0300 Subject: [PATCH 2/7] Added protocol --- udp/CurrencyApplicationProtocol | 66 +++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 udp/CurrencyApplicationProtocol diff --git a/udp/CurrencyApplicationProtocol b/udp/CurrencyApplicationProtocol new file mode 100644 index 0000000..e8c225b --- /dev/null +++ b/udp/CurrencyApplicationProtocol @@ -0,0 +1,66 @@ +Протокол разрабатывается исходя из подхода "запрос-ответ", так как он очень хорошо подходит для задачи: +клиенты запрашивают какое-то действие с валютой, сервер ее выполняет. + +Данные на сервере: + Массив валют, где валюта это: + Название валюты - 16 байта + История курса валюты - N * 4 байта (каждое значение курса это 4 байта) + +... - повторение описанных блоков выше. + +Клиент и сервер обмениваются пакетами раземра 508 байт (либо меньше, если размер сообщения небольшой). +В начале каждого пакета с запросом клиент передает -- номер его сессии, +и при получении ответа от сервера обрабатывает только те пакеты, которые соответствуют этой сессии. +Перед отправкой ответа с сервера содержимое сообщения разбивается на пакеты по 508 байт. +В начало каждого записывается служебная информация: + -- номер сессии, количество пакетов и порядковый номер текущего соответственно. +Клиент расставляет пришедшие пакеты в правильном порядке, при нехватке пакетов отправляет запрос заново с новым номером сессии. + +Поддерживаемые типы запросов: + 0. Получение и вывод списка валют с котировками/изменениями + Номер команды: 0. + + Клиент отправляет: "<номер команды: 4 байта>", + + Сервер отвечает: + "<название валюты: 16 байт><текущий курс: 4 байта><есть ли предыдущий курс: 1 байт><абсолютное приращение: 4 байта><относительное приращение: 4 байта>"..., + если предыдущего курса нет, то абсолютное и относительное значения равны нулям и игнорируются, + относительное значение выражается в процентах и округляется до целых. + Формулы: + абсолютное = current - previous + относительное = (current * 100.0) / previous + + 1. Передача команды на добавление валюты + Номер команды: 1. + + Клиент отправляет: "<номер команды: 4 байта><название валюты: 16 байт><текущий курс: 4 байта>", + + Сервер отвечает: + "<успех запроса: 1 байт>", + возвращает 1 если такой валюты еще не было, 0 если такая валюта была. + + 2. Передача команды на удаление валюты + Номер команды: 2. + + Клиент отправляет: "<номер команды: 4 байта><название валюты: 16 байт>", + + Сервер отвечает: + "<успех запроса: 1 байт>", + возвращает 1 если такая валюта была и была удалена успешно, 0 если такой валюты не было. + + 3. Передача команды на добавление курса валюты + Номер команды: 3. + + Клиент отправляет: "<номер команды: 4 байта><название валюты: 16 байт><новый курс: 4 байта>", + + Сервер отвечает: + "<успех запроса: 1 байт>", + возвращает 1 если успешно выставлен новый курс, 0 иначе. + + 4. Получение истории котировок валюты + Номер команды: 4. + + Клиент отправляет: "<номер команды: 4 байта><название валюты: 16 байт>", + + Сервер отвечает: + "<курс1: 4 байта><курс2: 4 байта>"... From f0d0b8e4a57c6724575b4cbb1c942feb61a2d81a Mon Sep 17 00:00:00 2001 From: VadimFarutin Date: Fri, 15 Mar 2019 13:39:58 +0300 Subject: [PATCH 3/7] Removed delimeters reading and writing --- udp/server/include/Server.h | 3 --- udp/server/src/Server.cpp | 29 ----------------------------- 2 files changed, 32 deletions(-) diff --git a/udp/server/include/Server.h b/udp/server/include/Server.h index 03ccba8..252315d 100644 --- a/udp/server/include/Server.h +++ b/udp/server/include/Server.h @@ -22,15 +22,12 @@ class Server { void processCurrencyRateHistoryQuery(); int32_t readCommand(); - int16_t readMessageDelimeter(); const std::string readCurrencyName(); int32_t readCurrencyRate(); int32_t readInt32(); - int16_t readInt16(); void readChars(char *dst, size_t size); - void sendMessageDelimeter(); void sendString(const std::string &message, size_t len); void sendInt32(int32_t n); void sendInt8(int8_t n); diff --git a/udp/server/src/Server.cpp b/udp/server/src/Server.cpp index 330fc17..ee35bf3 100644 --- a/udp/server/src/Server.cpp +++ b/udp/server/src/Server.cpp @@ -95,8 +95,6 @@ void Server::stop() const { } void Server::processCurrencyListQuery() { - readMessageDelimeter(); - for (auto it = currencies.begin(); it != currencies.end(); ++it) { Currency ¤cy = it->second; const string &name = currency.getName(); @@ -118,25 +116,21 @@ void Server::processCurrencyListQuery() { sendInt32(relativeChange); } - sendMessageDelimeter(); } void Server::processNewCurrencyQuery() { string name = readCurrencyName(); int32_t rate = readCurrencyRate(); - readMessageDelimeter(); Currency currency = Currency(name, rate); auto result = currencies.emplace(name, currency); int8_t success = result.second ? 1 : 0; sendInt8(success); - sendMessageDelimeter(); } void Server::processDeleteCurrencyQuery() { string name = readCurrencyName(); - readMessageDelimeter(); int8_t success; @@ -148,13 +142,11 @@ void Server::processDeleteCurrencyQuery() { } sendInt8(success); - sendMessageDelimeter(); } void Server::processAddCurrencyRateQuery() { string name = readCurrencyName(); int32_t rate = readCurrencyRate(); - readMessageDelimeter(); int8_t success; @@ -167,12 +159,10 @@ void Server::processAddCurrencyRateQuery() { } sendInt8(success); - sendMessageDelimeter(); } void Server::processCurrencyRateHistoryQuery() { string name = readCurrencyName(); - readMessageDelimeter(); Currency ¤cy = currencies.find(name)->second; auto rates = currency.getRates(); @@ -180,18 +170,12 @@ void Server::processCurrencyRateHistoryQuery() { for (auto rate : rates) { sendInt32(rate); } - - sendMessageDelimeter(); } int32_t Server::readCommand() { return readInt32(); } -int16_t Server::readMessageDelimeter() { - return readInt16(); -} - const string Server::readCurrencyName() { char name[CURRENCY_NAME_SIZE + 1]; bzero(name, CURRENCY_NAME_SIZE + 1); @@ -210,23 +194,11 @@ int32_t Server::readInt32() { return intValue; } -int16_t Server::readInt16() { - int16_t intValue = 0; - memcpy(&intValue, buffer + bufferPosition, sizeof(intValue)); - bufferPosition += sizeof(intValue); - return intValue; -} - void Server::readChars(char *dst, size_t size) { memcpy(dst, buffer + bufferPosition, size); bufferPosition += size; } -void Server::sendMessageDelimeter() { - sendInt8((int8_t) '\\'); - sendInt8(0); -} - void Server::sendString(const string &src, size_t len) { std::copy(src.begin(), src.end(), std::back_inserter(message)); @@ -245,4 +217,3 @@ void Server::sendInt32(int32_t d) { void Server::sendInt8(int8_t d) { message.push_back(d); } - From b439d3855be37b2d2d6326210f43bdd976db8413 Mon Sep 17 00:00:00 2001 From: VadimFarutin Date: Fri, 15 Mar 2019 13:48:40 +0300 Subject: [PATCH 4/7] Last packet can be smaller --- udp/server/src/Server.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udp/server/src/Server.cpp b/udp/server/src/Server.cpp index ee35bf3..6830318 100644 --- a/udp/server/src/Server.cpp +++ b/udp/server/src/Server.cpp @@ -76,11 +76,11 @@ void Server::start() { memcpy(writingBuffer, &dataSize, sizeof(int32_t)); memcpy(writingBuffer + sizeof(int32_t), ¤tDGram, sizeof(int32_t)); - for (int j = 0; j < BUFFER_SIZE && i + j < message.size(); j++) { + for (int j = 0; j < dataSize && i + j < message.size(); j++) { writingBuffer[2 * sizeof(int32_t) + j] = message[i + j]; } - n = sendto(sockfd, writingBuffer, BUFFER_SIZE, 0, (struct sockaddr*) &cli_addr, clilen); + n = sendto(sockfd, writingBuffer, min(BUFFER_SIZE, 2 * sizeof(int32_t) + message.size() - i), 0, (struct sockaddr*) &cli_addr, clilen); if (n < 0) { perror("ERROR on sending"); From 2e81af515a29959646833c815bf4bfdbb1e0570d Mon Sep 17 00:00:00 2001 From: VadimFarutin Date: Fri, 15 Mar 2019 20:02:12 +0300 Subject: [PATCH 5/7] Reading request id, handling empty message --- udp/server/include/Server.h | 4 +++- udp/server/src/Server.cpp | 42 ++++++++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/udp/server/include/Server.h b/udp/server/include/Server.h index 252315d..abc92f4 100644 --- a/udp/server/include/Server.h +++ b/udp/server/include/Server.h @@ -3,6 +3,7 @@ #include #include +#include #include "include/Currency.h" @@ -21,6 +22,7 @@ class Server { void processAddCurrencyRateQuery(); void processCurrencyRateHistoryQuery(); + int32_t readRequestId(); int32_t readCommand(); const std::string readCurrencyName(); int32_t readCurrencyRate(); @@ -35,7 +37,7 @@ class Server { void checkStatus(int n) const; static const int CURRENCY_NAME_SIZE = 16; - static const int BUFFER_SIZE = 508; + static const size_t BUFFER_SIZE = 508; int8_t buffer[BUFFER_SIZE]; int bufferPosition; std::vector message; diff --git a/udp/server/src/Server.cpp b/udp/server/src/Server.cpp index 6830318..f89cba2 100644 --- a/udp/server/src/Server.cpp +++ b/udp/server/src/Server.cpp @@ -6,9 +6,13 @@ #include #include #include +#include using namespace std; +const int Server::CURRENCY_NAME_SIZE; +const size_t Server::BUFFER_SIZE; + Server::Server(uint16_t portNumber) : portNumber(portNumber) {} @@ -41,12 +45,17 @@ void Server::start() { message.clear(); n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *) &cli_addr, &clilen); + + if (n == 0) { + break; + } if (n < 0) { perror("ERROR on receiving"); continue; } + int32_t requestId = readRequestId(); int32_t command = readCommand(); switch (command) { @@ -67,20 +76,39 @@ void Server::start() { break; } - int32_t dataSize = BUFFER_SIZE - 2 * sizeof(int32_t); + int32_t dataSize = BUFFER_SIZE - 3 * sizeof(int32_t); int32_t dGramNumber = (message.size() + dataSize - 1) / dataSize; + if (message.size() == 0) { + dGramNumber = 1; + int32_t currentDGram = 0; + + bzero((char *) &writingBuffer, BUFFER_SIZE); + memcpy(writingBuffer, &requestId, sizeof(int32_t)); + memcpy(writingBuffer + sizeof(int32_t), &dGramNumber, sizeof(int32_t)); + memcpy(writingBuffer + 2 * sizeof(int32_t), ¤tDGram, sizeof(int32_t)); + + n = sendto(sockfd, writingBuffer, 3 * sizeof(int32_t), 0, (struct sockaddr*) &cli_addr, clilen); + + if (n < 0) { + perror("ERROR on sending"); + } + + continue; + } + for (int32_t i = 0, currentDGram = 0; i < message.size(); i += dataSize, currentDGram++) { bzero((char *) &writingBuffer, BUFFER_SIZE); - memcpy(writingBuffer, &dataSize, sizeof(int32_t)); - memcpy(writingBuffer + sizeof(int32_t), ¤tDGram, sizeof(int32_t)); + memcpy(writingBuffer, &requestId, sizeof(int32_t)); + memcpy(writingBuffer + sizeof(int32_t), &dGramNumber, sizeof(int32_t)); + memcpy(writingBuffer + 2 * sizeof(int32_t), ¤tDGram, sizeof(int32_t)); for (int j = 0; j < dataSize && i + j < message.size(); j++) { - writingBuffer[2 * sizeof(int32_t) + j] = message[i + j]; + writingBuffer[3 * sizeof(int32_t) + j] = message[i + j]; } - n = sendto(sockfd, writingBuffer, min(BUFFER_SIZE, 2 * sizeof(int32_t) + message.size() - i), 0, (struct sockaddr*) &cli_addr, clilen); + n = sendto(sockfd, writingBuffer, min(BUFFER_SIZE, 3 * sizeof(int32_t) + message.size() - i), 0, (struct sockaddr*) &cli_addr, clilen); if (n < 0) { perror("ERROR on sending"); @@ -176,6 +204,10 @@ int32_t Server::readCommand() { return readInt32(); } +int32_t Server::readRequestId() { + return readInt32(); +} + const string Server::readCurrencyName() { char name[CURRENCY_NAME_SIZE + 1]; bzero(name, CURRENCY_NAME_SIZE + 1); From 58df381f819f502d734a766cd42e4c130691e00a Mon Sep 17 00:00:00 2001 From: VadimFarutin Date: Sat, 23 Mar 2019 20:44:41 +0300 Subject: [PATCH 6/7] Including pthread via find_package --- udp/server/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/udp/server/CMakeLists.txt b/udp/server/CMakeLists.txt index 82aaa47..ab80432 100644 --- a/udp/server/CMakeLists.txt +++ b/udp/server/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5) project(homework02) set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_FLAGS -lpthread) +find_package(Threads REQUIRED) include_directories(.) @@ -11,3 +11,4 @@ add_executable(homework02 src/Server.cpp include/Server.h src/Currency.cpp include/Currency.h) +target_link_libraries(homework02 Threads::Threads) From 9acc512d633d50053aa31f4ea616b89384c7a16a Mon Sep 17 00:00:00 2001 From: VadimFarutin Date: Sat, 23 Mar 2019 20:44:50 +0300 Subject: [PATCH 7/7] Checking port number value --- udp/server/src/CurrencyServerApplication.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/udp/server/src/CurrencyServerApplication.cpp b/udp/server/src/CurrencyServerApplication.cpp index dc0a3f6..1d9702f 100644 --- a/udp/server/src/CurrencyServerApplication.cpp +++ b/udp/server/src/CurrencyServerApplication.cpp @@ -11,9 +11,14 @@ int main(int argc, char *argv[]) { fprintf(stderr, "usage: .%s \n", argv[0]); return 0; } - uint16_t portNumber = static_cast(strtol(argv[1], nullptr, 10)); + long portNumber = strtol(argv[1], nullptr, 10); - Server server(portNumber); + if (portNumber <= 0 || portNumber > UINT16_MAX) { + fprintf(stderr, "illegal port number\n"); + return 0; + } + + Server server(static_cast(portNumber)); pthread_t serverThread; typedef void * (*PTHREAD_FUNC_PTR)(void *);