/
Mr.Stalin
/
FOnline-Engine
Обзор
Документация
Войти
/
Mr.Stalin
/
FOnline-Engine
Код
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Source/Essentials/NetSockets.h
135 строк
5 KB
cvet
Enhance socket error handling by introducing stable English messages for network errors; update NetworkServer to utilize new error reporting.
21 июл 2026, 15:02
21 июл 2026, 15:02
a19e9e7
Код
Авторство
О чём код?
// __________ ___ ______ _ // / ____/ __ \____ / (_)___ ___ / ____/___ ____ _(_)___ ___ // / /_ / / / / __ \/ / / __ \/ _ \ / __/ / __ \/ __ `/ / __ \/ _ ` // / __/ / /_/ / / / / / / / / / __/ / /___/ / / / /_/ / / / / / __/ // /_/ \____/_/ /_/_/_/_/ /_/\___/ /_____/_/ /_/\__, /_/_/ /_/\___/ // /____/ // FOnline Engine // https://fonline.ru // https://github.com/cvet/fonline // // MIT License // // Copyright (c) 2006 - 2026, Anton Tsvetinskiy aka cvet <cvet@tut.by> // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // #pragma once #include "BasicCore.h" #include "Containers.h" #include "TimeRelated.h" FO_BEGIN_NAMESPACE #if FO_WINDOWS using socket_t = uintptr_t; #else using socket_t = int32_t; #endif class net_sockets final { public: static auto startup() noexcept -> bool; static auto resolve_ipv4(string_view host) noexcept -> optional<uint32_t>; static auto ipv4_to_string(uint32_t addr_net_order) noexcept -> string; static auto host_to_net_u16(uint16_t value) noexcept -> uint16_t; static auto last_recv_was_would_block() noexcept -> bool; static auto error_text(const std::error_code& error) noexcept -> string; static auto last_error_text() noexcept -> string; }; class tcp_socket final { public: tcp_socket() noexcept = default; tcp_socket(const tcp_socket&) = delete; tcp_socket(tcp_socket&& other) noexcept = default; auto operator=(const tcp_socket&) -> tcp_socket& = delete; auto operator=(tcp_socket&& other) noexcept -> tcp_socket& = default; ~tcp_socket() = default; [[nodiscard]] auto is_valid() const noexcept -> bool { return !!_sock; } [[nodiscard]] auto native_handle() const noexcept -> socket_t { return _sock ? *_sock : socket_t {}; } auto connect(string_view host, uint16_t port) noexcept -> bool; auto connect_async(string_view host, uint16_t port) noexcept -> bool; // Use can_write(timeout) + peek_socket_error() to detect completion. auto can_read(timespan timeout = {}) const noexcept -> bool; auto can_write(timespan timeout = {}) const noexcept -> bool; auto set_nodelay(bool enabled) noexcept -> bool; auto peek_socket_error() const noexcept -> int32_t; // SO_ERROR via getsockopt; 0 if no pending error, -1 if call itself failed. auto send(const_span<uint8_t> data) noexcept -> int32_t; auto receive(span<uint8_t> data) noexcept -> int32_t; void close() noexcept; private: friend class tcp_server; explicit tcp_socket(socket_t sock) noexcept; unique_del_nptr<socket_t> _sock; }; class tcp_server final { public: tcp_server() noexcept = default; tcp_server(const tcp_server&) = delete; tcp_server(tcp_server&& other) noexcept = default; auto operator=(const tcp_server&) -> tcp_server& = delete; auto operator=(tcp_server&& other) noexcept -> tcp_server& = default; ~tcp_server() = default; [[nodiscard]] auto is_valid() const noexcept -> bool { return !!_listenSock; } auto listen(string_view bind_host, uint16_t port, int32_t backlog = 1) noexcept -> bool; auto can_accept(timespan timeout = {}) const noexcept -> bool; auto accept() noexcept -> tcp_socket; void close() noexcept; private: unique_del_nptr<socket_t> _listenSock; }; class udp_socket final { public: udp_socket() noexcept = default; udp_socket(const udp_socket&) = delete; udp_socket(udp_socket&& other) noexcept = default; auto operator=(const udp_socket&) -> udp_socket& = delete; auto operator=(udp_socket&& other) noexcept -> udp_socket& = default; ~udp_socket() = default; [[nodiscard]] auto is_valid() const noexcept -> bool { return !!_sock; } auto bind(string_view bind_host, uint16_t port, bool reuse_addr = true) noexcept -> bool; auto can_read(timespan timeout = {}) const noexcept -> bool; auto can_write(timespan timeout = {}) const noexcept -> bool; auto set_broadcast(bool enabled) noexcept -> bool; auto send_to(string_view host, uint16_t port, const_span<uint8_t> data) noexcept -> int32_t; auto receive_from(span<uint8_t> data, string& out_host, uint16_t& out_port) noexcept -> int32_t; void close() noexcept; private: unique_del_nptr<socket_t> _sock; }; FO_END_NAMESPACE