Files
CPP_Core/Socket_old/NetError.h
T
2026-06-16 10:56:40 +08:00

137 lines
4.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#ifndef PLANTSUNCAT_ERRC_H
#define PLANTSUNCAT_ERRC_H
#include "Core/Base/export.h"
namespace Psc::socket {
enum class NetError : unsigned char {
// ===== 通用 / 取消 / 参数 =====
unknown_error, // 被信号/中断打断(EINTR / WSAEINTR
interrupted, // 被信号/中断打断(EINTR / WSAEINTR
operation_canceled, // 取消(ECANCELED / WSAECANCELLED
invalid_argument, // 参数非法(EINVAL / WSAEINVAL
not_supported, // 不支持(EOPNOTSUPP/ENOTSUP 等)
permission_denied, // 权限不足(EACCES
out_of_memory, // 内存不足(ENOMEM
resource_exhausted, // 资源耗尽(EMFILE/ENFILE/ENOBUFS 等)
// ===== I/O / 系统 =====
io_error, // 其他 I/O 错误(EIO 等)
bad_file_descriptor, // fd 无效(EBADF
not_a_socket, // 不是 socketENOTSOCK / WSAENOTSOCK)
// ===== 非阻塞 / 状态 =====
would_block, // 非阻塞下暂时无数据/不可写(EAGAIN/EWOULDBLOCK / WSAEWOULDBLOCK
in_progress, // 操作进行中(EINPROGRESS / WSAEINPROGRESS
already_in_progress, // 已经在进行(EALREADY / WSAEALREADY
// ===== 地址 / 协议 =====
address_in_use, // 地址端口被占用(EADDRINUSE / WSAEADDRINUSE
address_not_available, // 地址不可用(EADDRNOTAVAIL / WSAEADDRNOTAVAIL
network_down, // 网络子系统 downENETDOWN / WSAENETDOWN
network_unreachable, // 网络不可达(ENETUNREACH / WSAENETUNREACH
host_unreachable, // 主机不可达(EHOSTUNREACH / WSAEHOSTUNREACH
protocol_error, // 协议/选项错误(EPROTO/EPROTOTYPE/ENOPROTOOPT...
// ===== 连接语义(TCP 核心)=====
not_connected, // 未连接(ENOTCONN / WSAENOTCONN
already_connected, // 已连接(EISCONN / WSAEISCONN
connection_refused, // 连接被拒绝(ECONNREFUSED / WSAECONNREFUSED
connection_reset, // 连接被重置(ECONNRESET / WSAECONNRESET
connection_aborted, // 连接被中止(ECONNABORTED / WSAECONNABORTED
connection_closed, // 对端正常关闭/EOF(recv 返回 0 的语义)
timed_out, // 超时(ETIMEDOUT / WSAETIMEDOUT
broken_pipe, // 写入已关闭连接(EPIPEWindows 近似用 shutdown/notconn/reset
// ===== DNS / 名称解析(可选但建议)=====
dns_not_found, // host 不存在/找不到(HOST_NOT_FOUND
dns_temporary_failure, // 临时失败(TRY_AGAIN
dns_failure, // 其他解析失败(NO_RECOVERY / 语义较泛)
};
class NetErrorCategory final : public std::error_category {
public:
[[nodiscard]] const char* name() const noexcept override {
// enum_type_name 返回 string_view,静态存储即可
static constexpr auto name_sv = magic_enum::enum_type_name<NetError>();
return name_sv.data();
}
[[nodiscard]] std::string message(int ev) const override {
auto opt = magic_enum::enum_name(static_cast<NetError>(ev));
if (!opt.empty())
return std::string(opt);
return "unknown enum error";
}
[[nodiscard]] bool equivalent(const std::error_code& ec, int cond) const noexcept override {
if (ec.category() != std::system_category()) return false;
return map_system_error(ec.value()) == static_cast<NetError>(cond);
}
static NetError map_system_error(int e) noexcept;
};
inline const std::error_category& net_category() {
static NetErrorCategory cat;
return cat;
}
ERROR_CODE_TYPE last_socket_ec();
template <typename T> using Ret = expected<T, Enum_Err<NetError>>;
extern BaseLogger *socket_logger;
#if WIN32
using Socket_FD = unsigned long long;
#else
using Socket_FD = int;
#endif
// 默认IPV4 TCP
enum class Socket_Type { TCP, UDP, Null };
struct Sockaddr_In {
std::string ip;
std::uint32_t port{};
[[nodiscard]] std::string to_string() const;
Sockaddr_In() = default;
Sockaddr_In(const std::string &ip, std::uint32_t port) {
this->ip = ip;
this->port = port;
}
// 定义小于运算符,便于存入 std::set
bool operator<(const Sockaddr_In &other) const {
// 先比较 IP 地址
if (ip != other.ip) {
return ip < other.ip;
}
// 如果 IP 地址相同,再比较端口号
return port < other.port;
}
bool operator==(const Sockaddr_In &other) const noexcept {
return ip == other.ip && port == other.port;
}
bool operator!=(const Sockaddr_In &other) const noexcept {
return !(*this == other);
}
};
struct Accept_Info {
Sockaddr_In sockaddr;
Socket_FD fd{};
[[nodiscard]] std::string to_string() const {
return "fd:" + std::to_string(fd) + ":[" + sockaddr.to_string() + "]";
}
};
}
#endif