From 65b6aedf86089be2654ed384d33eab03bbea3a7c Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Sat, 8 Nov 2025 19:55:29 +0300 Subject: [PATCH] Labs 3 & 4 implementation --- CMakeLists.txt | 2 +- modules/exceptions/src/exception.cppm | 2 +- modules/sockets/src/berkeley/context.cppm | 6 +- modules/sockets/src/berkeley/datagram.cppm | 10 +- modules/sockets/src/berkeley/stream.cppm | 14 +- modules/sockets/src/platform/windows.cpp.inc | 44 +++-- modules/streams/src/abstract.cppm | 6 +- programs/lab34/CMakeLists.txt | 17 ++ programs/lab34/src/_ping.cpp | 104 ++++++++++++ programs/lab34/src/ping_tcp.cpp | 5 + programs/lab34/src/ping_udp.cpp | 5 + programs/lab34/src/pong.cpp | 160 +++++++++++++++++++ programs/lab34/src/pong_tcp.cpp | 5 + programs/lab34/src/pong_udp.cpp | 5 + programs/lab34/src/variant.hpp | 25 +++ programs/lab4/CMakeLists.txt | 5 - programs/lab4/src/ping.cpp | 80 ---------- programs/lab4/src/pong.cpp | 83 ---------- programs/lab4/src/pong_async.cpp | 94 ----------- 19 files changed, 378 insertions(+), 294 deletions(-) create mode 100644 programs/lab34/CMakeLists.txt create mode 100644 programs/lab34/src/_ping.cpp create mode 100644 programs/lab34/src/ping_tcp.cpp create mode 100644 programs/lab34/src/ping_udp.cpp create mode 100644 programs/lab34/src/pong.cpp create mode 100644 programs/lab34/src/pong_tcp.cpp create mode 100644 programs/lab34/src/pong_udp.cpp create mode 100644 programs/lab34/src/variant.hpp delete mode 100644 programs/lab4/CMakeLists.txt delete mode 100644 programs/lab4/src/ping.cpp delete mode 100644 programs/lab4/src/pong.cpp delete mode 100644 programs/lab4/src/pong_async.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ba0c558..b410535 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,7 +26,7 @@ add_subdirectory(modules/streams) add_subdirectory(modules/sockets) add_subdirectory(modules/asyncio) -add_subdirectory(programs/lab4) +add_subdirectory(programs/lab34) add_executable(main main.cpp) target_link_libraries(main PRIVATE exceptions threads sockets streams) diff --git a/modules/exceptions/src/exception.cppm b/modules/exceptions/src/exception.cppm index 1e1b37c..3e067ff 100644 --- a/modules/exceptions/src/exception.cppm +++ b/modules/exceptions/src/exception.cppm @@ -44,7 +44,7 @@ namespace LdH { template requires std::invocable && std::same_as, void> && std::invocable && std::same_as, void> - void run_catching(prefix_printer_t const &prefix_printer, routine_t const &routine) { + void run_catching(prefix_printer_t const &prefix_printer, routine_t &routine) { try { routine(); } catch (LdH::Exception const &e) { diff --git a/modules/sockets/src/berkeley/context.cppm b/modules/sockets/src/berkeley/context.cppm index 00d1212..ae7471b 100644 --- a/modules/sockets/src/berkeley/context.cppm +++ b/modules/sockets/src/berkeley/context.cppm @@ -25,9 +25,9 @@ namespace LdH::Sockets::Berkeley { requires(typename ctx_t::socket_t s, typename ctx_t::address_t e) { { s.connect(e) } -> std::same_as; } && requires(typename ctx_t::socket_t s, typename ctx_t::address_t e) { { s.bind(e) } -> std::same_as; } && requires(typename ctx_t::socket_t s) { { s.close() } -> std::same_as; } && - requires(typename ctx_t::socket_t s, std::size_t c, char const *d) { { s.send_stream(c, d) } -> std::same_as; } && - requires(typename ctx_t::socket_t s, std::size_t c, char *d) { { s.recv_stream(c, d) } -> std::same_as; } && - requires(typename ctx_t::socket_t s, std::size_t c, char *d) { { s.recv_datagram(c, d) } -> std::same_as; } && + requires(typename ctx_t::socket_t s, std::size_t *c, char const *d, bool r) { { s.send_stream(c, d, r) } -> std::same_as; } && + requires(typename ctx_t::socket_t s, std::size_t *c, char *d, bool r) { { s.recv_stream(c, d, r) } -> std::same_as; } && + requires(typename ctx_t::socket_t s, std::size_t *c, char *d) { { s.recv_datagram(c, d) } -> std::same_as; } && requires(typename ctx_t::socket_t s, typename ctx_t::address_t e, std::size_t c, char const *d) { { s.send_datagram(e, c, d) } -> std::same_as; } && requires(typename ctx_t::socket_t s, typename ctx_t::address_t *a) { { s.accept(a) } -> std::same_as; }; } diff --git a/modules/sockets/src/berkeley/datagram.cppm b/modules/sockets/src/berkeley/datagram.cppm index 994dc39..00e8155 100644 --- a/modules/sockets/src/berkeley/datagram.cppm +++ b/modules/sockets/src/berkeley/datagram.cppm @@ -190,7 +190,7 @@ namespace LdH::Sockets::Berkeley { ServerDatagramSocket &operator=(ServerDatagramSocket &&other) noexcept = default; public: - Address recvOneTruncating(std::size_t size, char *data) { + Address recvOneTruncating(std::size_t *size, char *data) { this->_start_usage(); auto addr = this->_value.recv_datagram(size, data); this->_finish_usage(); @@ -199,7 +199,7 @@ namespace LdH::Sockets::Berkeley { void sendOne(Address destination, std::size_t size, char const *data) { this->_start_usage(); - this->_value.send_datagram(destination, size, data); + this->_value.send_datagram(_addr_internals::unwrap(destination), size, data); this->_finish_usage(); } @@ -238,15 +238,15 @@ namespace LdH::Sockets::Berkeley { ClientDatagramSocket &operator=(ClientDatagramSocket &&other) noexcept = default; public: - void recvOneTruncating(std::size_t size, char *data) override { + void recvOneTruncating(std::size_t *size, char *data) override { this->_start_usage(); - this->_value.recv_stream(size, data); + this->_value.recv_stream(size, data, false); this->_finish_usage(); } void sendOne(std::size_t size, char const *data) override { this->_start_usage(); - this->_value.send_stream(size, data); + this->_value.send_stream(&size, data, false); this->_finish_usage(); } diff --git a/modules/sockets/src/berkeley/stream.cppm b/modules/sockets/src/berkeley/stream.cppm index d1847aa..82ddfa8 100644 --- a/modules/sockets/src/berkeley/stream.cppm +++ b/modules/sockets/src/berkeley/stream.cppm @@ -208,16 +208,18 @@ namespace LdH::Sockets::Berkeley { StreamSocket &operator=(StreamSocket &&other) noexcept = default; - void read(std::size_t size, char *data) override { + bool read(std::size_t *size, char *data) override { this->_start_reading("Socket already read by another thread"); - this->_value.recv_stream(size, data); + bool closed = this->_value.recv_stream(size, data, true); this->_finish_reading(); + return closed; } - void write(std::size_t size, char const *data) override { + bool write(std::size_t *size, char const *data) override { this->_start_writing("Socket already written by another thread"); - this->_value.send_stream(size, data); + bool closed = this->_value.send_stream(size, data, true); this->_finish_writing(); + return closed; } void close() override { @@ -261,7 +263,9 @@ namespace LdH::Sockets::Berkeley { typename ctx_t::socket_t raw = this->_value.accept(&addr_raw); this->_finish_reading(); - *addr = std::move(_addr_internals::wrap(addr_raw)); + if (addr != nullptr) + *addr = std::move(_addr_internals::wrap(addr_raw)); + return _socket_internals >::wrap(std::move(raw)); } diff --git a/modules/sockets/src/platform/windows.cpp.inc b/modules/sockets/src/platform/windows.cpp.inc index d27c01c..08b2e67 100644 --- a/modules/sockets/src/platform/windows.cpp.inc +++ b/modules/sockets/src/platform/windows.cpp.inc @@ -135,7 +135,8 @@ namespace LdH::Sockets { } socket_t accept(address_t *addr) { - SOCKET sock = ::accept(this->_value, reinterpret_cast(&(addr->_value)), nullptr); + int addrlen = sizeof(sockaddr_storage); + SOCKET sock = ::accept(this->_value, reinterpret_cast(&(addr->_value)), &addrlen); if (sock == INVALID_SOCKET) { LdH::throwFromWindowsErrCode(WSAGetLastError()); } @@ -149,27 +150,41 @@ namespace LdH::Sockets { } - void send_stream(std::size_t size, char const *data) { + bool send_stream(std::size_t *size, char const *data, bool repeat) { + size_t expected_size = *size; + *size = 0; while (true) { - std::size_t sent_count = ::send(this->_value, data, size, 0); + std::size_t sent_count = ::send(this->_value, data, expected_size, 0); if (sent_count == SOCKET_ERROR) { LdH::throwFromWindowsErrCode(WSAGetLastError()); } + data += sent_count; - size -= sent_count; - if (size <= 0) return; + expected_size -= sent_count; + *size += sent_count; + if (expected_size <= 0) return false; + if (!repeat) return false; } } - void recv_stream(std::size_t size, char *data) { + bool recv_stream(std::size_t *size, char *data, bool repeat) { + size_t expected_size = *size; + *size = 0; while (true) { - std::size_t sent_count = ::recv(this->_value, data, size, 0); - if (sent_count == SOCKET_ERROR) { - LdH::throwFromWindowsErrCode(WSAGetLastError()); + std::size_t read_count = ::recv(this->_value, data, expected_size, 0); + switch (read_count) { + case SOCKET_ERROR: + LdH::throwFromWindowsErrCode(WSAGetLastError()); + case 0: + return true; + default: + break; } - data += sent_count; - size -= sent_count; - if (size <= 0) return; + data += read_count; + expected_size -= read_count; + *size += read_count; + if (expected_size <= 0) return false; + if (!repeat) return false; } } @@ -180,13 +195,14 @@ namespace LdH::Sockets { } } - address_t recv_datagram(std::size_t size, char *data) { + address_t recv_datagram(std::size_t *size, char *data) { address_t out; int out_size = sizeof(out); - int sent_count = ::recvfrom(this->_value, data, size, 0, reinterpret_cast(&out), &out_size); + int sent_count = ::recvfrom(this->_value, data, *size, 0, reinterpret_cast(&out), &out_size); if (sent_count == SOCKET_ERROR) { LdH::throwFromWindowsErrCode(WSAGetLastError()); } + *size = sent_count; return out; } }; diff --git a/modules/streams/src/abstract.cppm b/modules/streams/src/abstract.cppm index 2d46d60..f935fe5 100644 --- a/modules/streams/src/abstract.cppm +++ b/modules/streams/src/abstract.cppm @@ -5,7 +5,7 @@ import std; namespace LdH::Streams { export class OutputStream { public: - virtual void write(std::size_t, char const *) = 0; + virtual bool write(std::size_t *, char const *) = 0; virtual void close() = 0; @@ -14,7 +14,7 @@ namespace LdH::Streams { export class InputStream { public: - virtual void read(std::size_t, char *) = 0; + virtual bool read(std::size_t *, char *) = 0; virtual void close() = 0; @@ -33,7 +33,7 @@ namespace LdH::Streams { export class InputMessanger { public: - virtual void recvOneTruncating(std::size_t, char *) = 0; + virtual void recvOneTruncating(std::size_t *, char *) = 0; virtual void close() = 0; diff --git a/programs/lab34/CMakeLists.txt b/programs/lab34/CMakeLists.txt new file mode 100644 index 0000000..9996681 --- /dev/null +++ b/programs/lab34/CMakeLists.txt @@ -0,0 +1,17 @@ +add_library(lab34_ping_ OBJECT src/_ping.cpp src/variant.hpp) +target_link_libraries(lab34_ping_ PRIVATE sockets exceptions) + +add_executable(lab34_ping_tcp src/ping_tcp.cpp) +target_link_libraries(lab34_ping_tcp PRIVATE lab34_ping_) + +add_executable(lab34_ping_udp src/ping_udp.cpp) +target_link_libraries(lab34_ping_udp PRIVATE lab34_ping_) + +add_library(lab34_pong_ OBJECT ./src/pong.cpp src/variant.hpp) +target_link_libraries(lab34_pong_ PRIVATE sockets exceptions) + +add_executable(lab34_pong_tcp src/pong_tcp.cpp) +target_link_libraries(lab34_pong_tcp PRIVATE lab34_pong_) + +add_executable(lab34_pong_udp src/pong_udp.cpp) +target_link_libraries(lab34_pong_udp PRIVATE lab34_pong_) \ No newline at end of file diff --git a/programs/lab34/src/_ping.cpp b/programs/lab34/src/_ping.cpp new file mode 100644 index 0000000..76ca69b --- /dev/null +++ b/programs/lab34/src/_ping.cpp @@ -0,0 +1,104 @@ +import std; +import ru.landgrafhomyak.BGTU.networks_1.exceptions; +import ru.landgrafhomyak.BGTU.networks_1.sockets; + +#include "variant.hpp" + +namespace +{ + template + class PingVariant + { + }; + + template <> + class PingVariant + { + using socket_t = LdH::Sockets::StreamSocket; + + static socket_t connect(LdH::Sockets::Address& addr) + { + return LdH::Sockets::connect_tcp(addr); + } + }; +} + +template +int ping_main(int argc, char const* const* argv) +{ + int ret_v; + bool was_error = true; + LdH::run_catching_main([&] + { + if (argc != 3 && argc != 4) + { + std::cout << "Wrong CLI arguments count: " << (argc - 1) << "\n"; + std::cout << "Usage: " << argv[0] << " {dst_addr} {payload}" << std::endl; + std::cout << "Usage: " << argv[0] << " {dst_addr} {port/service} {payload}" << std::endl; + ret_v = 1, was_error = false; + return; + } + + std::size_t payload_size = std::strlen(argv[(argc == 3 ? 2 : 3)]); + + if (payload_size > 255) + { + std::cout << "Payloand too long: " << payload_size << "\n"; + std::cout << "Maximum payload size is 255" << std::endl; + ret_v = 1, was_error = false; + return; + } + + char payload[256]; + payload[0] = static_cast(payload_size); + std::memcpy(payload + 1, argv[(argc == 3 ? 2 : 3)], payload_size); + payload_size++; + + + LdH::Sockets::init_sockets(); + auto dst = LdH::Sockets::Address::parse(argv[1], (argc == 3 ? nullptr : argv[2])); + + + if constexpr (PING_TYPE == Protocol::TCP) + { + auto sock = LdH::Sockets::connect_tcp(dst); + + sock.write(&payload_size, payload); + std::cout << "Sent " << payload_size << " bytes\nReceiving:\n\n"; + std::cout.flush(); + + while (true) + { + char buff[1024]; + std::size_t buff_size = sizeof(buff); + bool is_closed = sock.read(&buff_size, buff); + std::cout << std::string{buff, buff_size}; + if (is_closed) break; + } + + sock.close(); + ret_v = 0, was_error = false; + } + else if constexpr (PING_TYPE == Protocol::UDP) + { + auto sock = LdH::Sockets::connect_udp(dst); + + sock.sendOne(payload_size, payload); + std::cout << "Sent " << payload_size << " bytes\nReceiving:\n\n"; + std::cout.flush(); + + char buff[65536]; + std::size_t buff_size = sizeof(buff); + sock.recvOneTruncating(&buff_size, buff); + std::cout << std::string{buff, buff_size}; + + sock.close(); + ret_v = 0, was_error = false; + } + LdH::Sockets::deinit_sockets(); + }); + + if (was_error) + return 3; + return ret_v; +} diff --git a/programs/lab34/src/ping_tcp.cpp b/programs/lab34/src/ping_tcp.cpp new file mode 100644 index 0000000..b15fb86 --- /dev/null +++ b/programs/lab34/src/ping_tcp.cpp @@ -0,0 +1,5 @@ +#include "variant.hpp" + +int main(int argc, char const *const*argv) { + return ping_main(argc, argv); +} diff --git a/programs/lab34/src/ping_udp.cpp b/programs/lab34/src/ping_udp.cpp new file mode 100644 index 0000000..3f8aa82 --- /dev/null +++ b/programs/lab34/src/ping_udp.cpp @@ -0,0 +1,5 @@ +#include "variant.hpp" + +int main(int argc, char const *const*argv) { + return ping_main(argc, argv); +} diff --git a/programs/lab34/src/pong.cpp b/programs/lab34/src/pong.cpp new file mode 100644 index 0000000..53b929c --- /dev/null +++ b/programs/lab34/src/pong.cpp @@ -0,0 +1,160 @@ +import std; +import ru.landgrafhomyak.BGTU.networks_1.exceptions; +import ru.landgrafhomyak.BGTU.networks_1.sockets; + +#include "variant.hpp" + +namespace +{ + class ByteCounter + { + private: + std::size_t bytes[std::numeric_limits::max() - std::numeric_limits::min() + 1]; + + public: + ByteCounter() : bytes{} + { + for (auto& e : this->bytes) + { + e = 0; + } + } + + std::size_t& operator[](char c) + { + return this->bytes[c - std::numeric_limits::min()]; + } + + void apply(char const* payload, std::size_t count) + { + for (std::size_t i = 0; i < count; i++) + this->operator[](payload[i])++; + } + + void print(std::ostream& out) + { + for (char c = std::numeric_limits::min(); c < std::numeric_limits::max(); c++) + { + if (this->operator[](c) != 0) + { + out << static_cast(c) << ": " << this->operator[](c) << " times\n"; + } + } + if (this->operator[](std::numeric_limits::max()) != 0) + { + out << static_cast(std::numeric_limits::max()) << ": " << this->operator[]( + std::numeric_limits::max()) << " times\n"; + } + } + }; + + void do_tcp(LdH::Sockets::Address& listen_addr) + { + auto server = LdH::Sockets::listen_tcp(listen_addr, 10); + + while (true) + { + LdH::Sockets::Address addr; + auto sock = server.wait_for_connection(&addr); + std::cout << "Connection from " << addr.to_string() << std::endl; + + std::size_t read_count; + bool closed; + + char payload_size; + read_count = 1; + closed = sock.read(&read_count, &payload_size); + if (closed) + { + sock.close(); + continue; + } + + char payload[255]; + read_count = static_cast(payload_size); + closed = sock.read(&read_count, payload); + if (closed) + { + sock.close(); + continue; + } + + ByteCounter counter; + counter.apply(payload, read_count); + + std::stringstream resp_builder; + resp_builder << "Bytes summary:\n"; + counter.print(resp_builder); + + auto resp = resp_builder.str(); + read_count = resp.length(); + + sock.write(&read_count, resp.c_str()); + + sock.close(); + } + } + + void do_udp(LdH::Sockets::Address& listen_addr) + { + auto server = LdH::Sockets::listen_udp(listen_addr); + + while (true) + { + char payload[65536]; + std::size_t read_count = 65536; + LdH::Sockets::Address addr = server.recvOneTruncating(&read_count, payload); + + std::cout << "Connection from " << addr.to_string() << std::endl; + + + ByteCounter counter; + counter.apply(payload, read_count); + + std::stringstream resp_builder; + resp_builder << "Bytes summary:\n"; + counter.print(resp_builder); + + auto resp = resp_builder.str(); + read_count = resp.length(); + + server.sendOne(addr, read_count, resp.c_str()); + } + server.close(); + } +} + +template +int pong_main(int argc, char const* const* argv) +{ + int ret_v; + bool was_error = true; + LdH::run_catching_main([&] + { + if (argc != 2 && argc != 3) + { + std::cout << "Wrong CLI arguments count: " << (argc - 1) << "\n"; + std::cout << "Usage: " << argv[0] << " {listen_addr}" << std::endl; + std::cout << "Usage: " << argv[0] << " {listen_addr} {port/service}" << std::endl; + ret_v = 1, was_error = false; + return; + } + LdH::Sockets::init_sockets(); + + auto addr = LdH::Sockets::Address::parse(argv[1], (argc == 2 ? nullptr : argv[2])); + + if constexpr (PROTOCOL == Protocol::TCP) + { + do_tcp(addr); + } + else if constexpr (PROTOCOL == Protocol::UDP) + { + do_udp(addr); + } + LdH::Sockets::deinit_sockets(); + }); + + if (was_error) + return 3; + return ret_v; +} diff --git a/programs/lab34/src/pong_tcp.cpp b/programs/lab34/src/pong_tcp.cpp new file mode 100644 index 0000000..8e73f06 --- /dev/null +++ b/programs/lab34/src/pong_tcp.cpp @@ -0,0 +1,5 @@ +#include "variant.hpp" + +int main(int argc, char const *const*argv) { + return pong_main(argc, argv); +} diff --git a/programs/lab34/src/pong_udp.cpp b/programs/lab34/src/pong_udp.cpp new file mode 100644 index 0000000..1468372 --- /dev/null +++ b/programs/lab34/src/pong_udp.cpp @@ -0,0 +1,5 @@ +#include "variant.hpp" + +int main(int argc, char const *const*argv) { + return pong_main(argc, argv); +} diff --git a/programs/lab34/src/variant.hpp b/programs/lab34/src/variant.hpp new file mode 100644 index 0000000..ad38a4a --- /dev/null +++ b/programs/lab34/src/variant.hpp @@ -0,0 +1,25 @@ +#pragma once + +enum class Protocol { + TCP, + UDP, +}; + +template +extern int ping_main(int argc, char const* const* argv); + +template +int ping_main(int, char const* const*); + +template +int ping_main(int, char const* const*); + + +template +extern int pong_main(int argc, char const* const* argv); + +template +int pong_main(int, char const* const*); + +template +int pong_main(int, char const* const*); diff --git a/programs/lab4/CMakeLists.txt b/programs/lab4/CMakeLists.txt deleted file mode 100644 index 37d583b..0000000 --- a/programs/lab4/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -add_executable(lab4_ping ./src/ping.cpp) -add_executable(lab4_pong ./src/pong.cpp) - -target_link_libraries(lab4_ping PRIVATE wsock32 ws2_32 exceptions asyncio) -target_link_libraries(lab4_pong PRIVATE wsock32 ws2_32 exceptions asyncio) \ No newline at end of file diff --git a/programs/lab4/src/ping.cpp b/programs/lab4/src/ping.cpp deleted file mode 100644 index b5340fa..0000000 --- a/programs/lab4/src/ping.cpp +++ /dev/null @@ -1,80 +0,0 @@ - -#include -#include -#include -#include -#include - - -static void ping() { - SOCKET sock = WSASocketW( - AF_INET, - SOCK_DGRAM, - 0, - nullptr, - 0, - /*WSA_FLAG_OVERLAPPED | */WSA_FLAG_NO_HANDLE_INHERIT - ); - if (sock == INVALID_SOCKET) - LdH::Exception::throwFromWindowsErrCode(WSAGetLastError()); - - - sockaddr selfaddr; - INT selfaddrlen = sizeof(sockaddr); - - if (SOCKET_ERROR == WSAStringToAddressW((wchar_t *) L"127.0.0.1:8082", AF_INET, nullptr, &selfaddr, &selfaddrlen)) - LdH::Exception::throwFromWindowsErrCode(WSAGetLastError()); - - - while (true) { - char buffer[1024] = "hello world"; - WSABUF buffers_meta[1] = {{1024, buffer}}; - sockaddr addr; - INT addrlen = sizeof(sockaddr); - DWORD flags = 0;/* MSG_PARTIAL*/ - - DWORD transferred_count; - - auto res = WSASendTo( - sock, - buffers_meta, 1, - &transferred_count, - /* MSG_PARTIAL*/ 0, - &selfaddr, selfaddrlen, - nullptr, nullptr - ); - if (res == SOCKET_ERROR) { - LdH::Exception::throwFromWindowsErrCode(WSAGetLastError()); - } - - res = WSARecvFrom( - sock, - buffers_meta, 1, - &transferred_count, - &flags, - &addr, &addrlen, - nullptr, nullptr - ); - if (res == SOCKET_ERROR) { - LdH::Exception::throwFromWindowsErrCode(WSAGetLastError()); - } - - std::cout << buffer << std::endl; - } -} - -int main() { - try { - WSADATA wsaData; - auto wsa_init_res = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (wsa_init_res != ERROR_SUCCESS) - LdH::Exception::throwFromWindowsErrCode(wsa_init_res); - - ping(); - - - WSACleanup(); - } catch (LdH::Exception &e) { - e.printStackTrace(); - } -} \ No newline at end of file diff --git a/programs/lab4/src/pong.cpp b/programs/lab4/src/pong.cpp deleted file mode 100644 index 94a8c26..0000000 --- a/programs/lab4/src/pong.cpp +++ /dev/null @@ -1,83 +0,0 @@ - -#include -#include -#include -#include -#include - - -static void connections_listener() { - SOCKET sock = WSASocketW( - AF_INET, - SOCK_DGRAM, - 0, - nullptr, - 0, - /*WSA_FLAG_OVERLAPPED | */WSA_FLAG_NO_HANDLE_INHERIT - ); - if (sock == INVALID_SOCKET) - LdH::Exception::throwFromWindowsErrCode(WSAGetLastError()); - - - sockaddr selfaddr; - INT selfaddrlen = sizeof(sockaddr); - - if (SOCKET_ERROR == WSAStringToAddressW((wchar_t *) L"127.0.0.1:8082", AF_INET, nullptr, &selfaddr, &selfaddrlen)) - LdH::Exception::throwFromWindowsErrCode(WSAGetLastError()); - - if (SOCKET_ERROR == bind(sock, &selfaddr, selfaddrlen)) - LdH::Exception::throwFromWindowsErrCode(WSAGetLastError()); - - - while (true) { - char buffer[1024]; - WSABUF buffers_meta[1] = {{1024, buffer}}; - sockaddr addr; - INT addrlen = sizeof(sockaddr); - DWORD flags = 0;/* MSG_PARTIAL*/ - - DWORD transferred_count; - auto res = WSARecvFrom( - sock, - buffers_meta, 1, - &transferred_count, - &flags, - &addr, &addrlen, - nullptr, nullptr - ); - if (res == SOCKET_ERROR) { - LdH::Exception::throwFromWindowsErrCode(WSAGetLastError()); - } - - buffers_meta[0].len = transferred_count; - std::cout << buffer << std::endl; - - res = WSASendTo( - sock, - buffers_meta, 1, - &transferred_count, - /* MSG_PARTIAL*/ 0, - &addr, sizeof(sockaddr), - nullptr, nullptr - ); - if (res == SOCKET_ERROR) { - LdH::Exception::throwFromWindowsErrCode(WSAGetLastError()); - } - } -} - -int main() { - try { - WSADATA wsaData; - auto wsa_init_res = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (wsa_init_res != ERROR_SUCCESS) - LdH::Exception::throwFromWindowsErrCode(wsa_init_res); - - connections_listener(); - - - WSACleanup(); - } catch (LdH::Exception &e) { - e.printStackTrace(); - } -} \ No newline at end of file diff --git a/programs/lab4/src/pong_async.cpp b/programs/lab4/src/pong_async.cpp deleted file mode 100644 index 8893004..0000000 --- a/programs/lab4/src/pong_async.cpp +++ /dev/null @@ -1,94 +0,0 @@ - -#include -#include -#include -#include - -struct request_t { - char buffer[1024]; - WSABUF buffers_meta[1] = {{1024, buffer}}; - sockaddr addr; - SOCKET socket; -}; - -static void connections_listener(void *) { - SOCKET server = WSASocketW( - AF_INET, - SOCK_DGRAM, - 0, - nullptr, - 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT - ); - if (server == INVALID_SOCKET) - LdH::Exception::throwFromWindowsErrCode(WSAGetLastError()); - - while (true) { - auto req = new request_t{}; - req->socket = server; - - LdH::Asyncio::WindowsOverlappedEventloop::overlappedCall( - [&](LPOVERLAPPED o, LPOVERLAPPED_COMPLETION_ROUTINE ocr) -> DWORD { - DWORD recived_count; - auto res = WSARecvFrom( - server, - req->buffers_meta, 1, - &recived_count, - /* MSG_PARTIAL*/ nullptr, - &req->addr, nullptr, - o, reinterpret_cast(ocr) - ); - if (res == SOCKET_ERROR) { - auto err = WSAGetLastError(); - if (err == WSA_IO_PENDING) - return 0; - LdH::Exception::throwFromWindowsErrCode(err); - } - return recived_count; - } - ); - - - } -} - -static void answer(request_t *data) { - LdH::Asyncio::WindowsOverlappedEventloop::overlappedCall( - [&](LPOVERLAPPED o, LPOVERLAPPED_COMPLETION_ROUTINE ocr) -> DWORD { - DWORD recived_count; - auto res = WSASendTo( - data->socket, - data->buffers_meta, 1, - &recived_count, - /* MSG_PARTIAL*/ 0, - &data->addr, sizeof(sockaddr), - o, reinterpret_cast(ocr) - ); - if (res == SOCKET_ERROR) { - auto err = WSAGetLastError(); - if (err == WSA_IO_PENDING) - return 0; - LdH::Exception::throwFromWindowsErrCode(err); - } - return recived_count; - } - ); -} - -int main() { - try { - WSADATA wsaData; - auto wsa_init_res = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (wsa_init_res != ERROR_SUCCESS) - LdH::Exception::throwFromWindowsErrCode(wsa_init_res); - - LdH::Asyncio::WindowsOverlappedEventloop eventloop{}; - eventloop.addTask(&connections_listener, nullptr); - eventloop.runUntilHasTasksAndNotInterrupted(); - - - WSACleanup(); - } catch (LdH::Exception &e) { - e.printStackTrace(); - } -} \ No newline at end of file