From 8dc814b5fe2dbc9414dc8f08c45c6950a35f7c47 Mon Sep 17 00:00:00 2001 From: Alexander Zhirov Date: Mon, 5 Sep 2022 09:44:08 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=97:=20=D0=A3=D1=80=D0=BE=D0=BA=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lesson_01/client/udp.cpp | 21 ++++++ lesson_01/client/udp.h | 10 +++ lesson_01/headers/address.h | 55 ++++++++++++++++ lesson_01/headers/client.h | 67 +++++++++++++++++++ lesson_01/headers/server.h | 127 ++++++++++++++++++++++++++++++++++++ lesson_01/headers/socket.h | 48 ++++++++++++++ lesson_01/main.cpp | 19 ++++++ lesson_01/server/udp.cpp | 27 ++++++++ lesson_01/server/udp.h | 10 +++ 9 files changed, 384 insertions(+) create mode 100644 lesson_01/client/udp.cpp create mode 100644 lesson_01/client/udp.h create mode 100644 lesson_01/headers/address.h create mode 100644 lesson_01/headers/client.h create mode 100644 lesson_01/headers/server.h create mode 100644 lesson_01/headers/socket.h create mode 100644 lesson_01/main.cpp create mode 100644 lesson_01/server/udp.cpp create mode 100644 lesson_01/server/udp.h diff --git a/lesson_01/client/udp.cpp b/lesson_01/client/udp.cpp new file mode 100644 index 0000000..e7d2066 --- /dev/null +++ b/lesson_01/client/udp.cpp @@ -0,0 +1,21 @@ +/* + * udp.cpp + * + * Created on: 10 авг. 2022 г. + * Author: alexander + */ + +#include "udp.h" +#include "client.h" + +int clientUDP() +{ + azh::Client client; + + client.createUDP(1991); + client.start(); + + return 0; +} + + diff --git a/lesson_01/client/udp.h b/lesson_01/client/udp.h new file mode 100644 index 0000000..dacb7c3 --- /dev/null +++ b/lesson_01/client/udp.h @@ -0,0 +1,10 @@ +/* + * udp.h + * + * Created on: 10 авг. 2022 г. + * Author: alexander + */ + +#pragma once + +int clientUDP(); diff --git a/lesson_01/headers/address.h b/lesson_01/headers/address.h new file mode 100644 index 0000000..012c5d5 --- /dev/null +++ b/lesson_01/headers/address.h @@ -0,0 +1,55 @@ +/* + * address.h + * + * Created on: 9 авг. 2022 г. + * Author: alexander + */ + +#pragma once + +#include +#include + +namespace azh +{ + +class Address +{ +private: + struct sockaddr_in _addr; + unsigned int _len; +public: + Address(unsigned short int family, unsigned int addr, unsigned short int port) + { + memset(&_addr, 0, sizeof(_addr)); + _len = sizeof(_addr); + + _addr.sin_family = family; + _addr.sin_addr.s_addr = addr; + _addr.sin_port = htons(port); + } + + Address() + { + memset(&_addr, 0, sizeof(_addr)); + _len = sizeof(_addr); + } + + Address(Address &address) + { + _addr = address._addr; + _len = address._len; + } + + unsigned int& size() + { + return _len; + } + + struct sockaddr_in& operator*() + { + return _addr; + } +}; + +} diff --git a/lesson_01/headers/client.h b/lesson_01/headers/client.h new file mode 100644 index 0000000..93aa60d --- /dev/null +++ b/lesson_01/headers/client.h @@ -0,0 +1,67 @@ +/* + * client.h + * + * Created on: 10 авг. 2022 г. + * Author: alexander + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include + +#define MAXLINE 1024 + +namespace azh +{ + +class Client +{ +private: + Socket _socket; + Address _address; + char _buffer[MAXLINE]; + long int _recv_len; +public: + Client(Socket &socket, Address &address) : + _socket(socket), _address(address), _recv_len(0) + { + } + + Client() : + _recv_len(0) + { + } + + void createUDP(unsigned short int port) + { + _socket = { AF_INET, SOCK_DGRAM, IPPROTO_UDP }; + _address = { AF_INET, INADDR_ANY, port }; + } + + void start() + { + while (true) + { + char message[MAXLINE]; + message[MAXLINE] = '\0'; + std::cin.getline(message, MAXLINE); + + sendto(_socket, message, strlen(message), MSG_CONFIRM, reinterpret_cast(&_address), _address.size()); + + _recv_len = recvfrom(_socket, _buffer, MAXLINE - 1, MSG_WAITALL, reinterpret_cast(&_address), &_address.size()); + if (_recv_len > 0) + { + _buffer[_recv_len] = '\0'; + std::cout << _buffer << std::endl; + } + } + } +}; + +} diff --git a/lesson_01/headers/server.h b/lesson_01/headers/server.h new file mode 100644 index 0000000..940c410 --- /dev/null +++ b/lesson_01/headers/server.h @@ -0,0 +1,127 @@ +/* + * server.h + * + * Created on: 9 авг. 2022 г. + * Author: alexander + */ + +#pragma once + +#include +#include + +#include +#include +#include +#include + +#define MAXLINE 1024 + +namespace azh +{ + +class Server +{ +private: + Socket _socket; + Address _address; + Address _client; + char _buffer[MAXLINE]; + bool _listenLoop; + long int _recv_len; + + typedef void (*hPtr)(std::string buffer, Server &s); + + class Hook + { + private: + std::string _command; + hPtr _handler; + public: + Hook(std::string command, hPtr handler) : + _command(command), _handler(handler) + { + } + + void execute(std::string buffer, Server &s) + { + if (_command == "") + { + _handler(buffer, s); + } + else + { + auto pos = buffer.find_first_of(_command); + if (pos != std::string::npos && pos == 0) + { + _handler(buffer, s); + } + } + } + }; + + std::vector _hooks; + + void print(char *buffer) + { + std::string s_buffer(buffer); + std::cout << s_buffer; + } +public: + Server(Socket &socket, Address &address) : + _socket(socket), _address(address), _listenLoop(true), _recv_len(0) + { + } + + Server() : + _listenLoop(true), _recv_len(0) + { + } + + void createUDP(unsigned short int port) + { + _socket = { AF_INET, SOCK_DGRAM, IPPROTO_UDP }; + _address = { AF_INET, INADDR_ANY, port }; + } + + void bind() + { + if (::bind(_socket, reinterpret_cast(&_address), _address.size()) < 0) + { + perror("bind failed"); + exit(EXIT_FAILURE); + } + } + + void listen() + { + while (_listenLoop) + { + _recv_len = recvfrom(_socket, _buffer, MAXLINE - 1, MSG_WAITALL, reinterpret_cast(&_client), &_client.size()); + if (_recv_len > 0) + { + _buffer[_recv_len] = '\0'; + std::for_each(_hooks.begin(), _hooks.end(), [&](Hook &hook) + { + hook.execute(_buffer, *this); + }); + + const char *answer = "Сообщение получено!"; + + sendto(_socket, answer, strlen(answer), MSG_CONFIRM, reinterpret_cast(&_client), _client.size()); + } + } + } + + void registerHook(std::string command, hPtr handler) + { + _hooks.push_back( { command, handler }); + } + + void stop() + { + _listenLoop = false; + } +}; + +} diff --git a/lesson_01/headers/socket.h b/lesson_01/headers/socket.h new file mode 100644 index 0000000..924cbfa --- /dev/null +++ b/lesson_01/headers/socket.h @@ -0,0 +1,48 @@ +/* + * socket.h + * + * Created on: 9 авг. 2022 г. + * Author: alexander + */ + +#pragma once + +#include +#include +#include + +namespace azh +{ + +class Socket +{ +private: + int _sockfd; +public: + Socket(int domain, int type, int protocol) + { + if ((_sockfd = socket(domain, type, protocol)) < 0) + { + perror("socket creation failed"); + exit(EXIT_FAILURE); + } + } + + Socket(Socket &socket) + { + _sockfd = socket._sockfd; + } + + Socket() + { + _sockfd = -1; + } + + operator int() + { + return _sockfd; + } +}; + +} + diff --git a/lesson_01/main.cpp b/lesson_01/main.cpp new file mode 100644 index 0000000..c5003ad --- /dev/null +++ b/lesson_01/main.cpp @@ -0,0 +1,19 @@ +/* + * main.cpp + * + * Created on: 10 авг. 2022 г. + * Author: alexander + */ + +#include "server/udp.h" +#include "client/udp.h" + +int main() +{ + serverUDP(); +// clientUDP(); + + return 0; +} + + diff --git a/lesson_01/server/udp.cpp b/lesson_01/server/udp.cpp new file mode 100644 index 0000000..6b7272f --- /dev/null +++ b/lesson_01/server/udp.cpp @@ -0,0 +1,27 @@ +#include "server.h" +#include "udp.h" + +void print(std::string buffer, azh::Server &s) +{ + std::cout << buffer << std::endl; +} + +void stop(std::string buffer, azh::Server &s) +{ + s.stop(); +} + +int serverUDP() +{ + azh::Server server; + + server.createUDP(1991); + server.bind(); + + server.registerHook("", print); + server.registerHook("exit", stop); + + server.listen(); + + return 0; +} diff --git a/lesson_01/server/udp.h b/lesson_01/server/udp.h new file mode 100644 index 0000000..f73599f --- /dev/null +++ b/lesson_01/server/udp.h @@ -0,0 +1,10 @@ +/* + * udp.h + * + * Created on: 10 авг. 2022 г. + * Author: alexander + */ + +#pragma once + +int serverUDP(); -- 2.40.1