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

116 lines
3.8 KiB
C++

#ifndef SOCKET_H
#define SOCKET_H
#include "../Base/expected.h"
#include "../Base/export.h"
#include "../Base/codec.h"
#include "../JSON.h"
#include "Core/spdlog/export.h"
#include "NetError.h"
#include <cstdint>
#include <set>
/*
套接字连接过程 客户端(发数据端口)/服务端(收数据端口)
1. 创建套接字
2. 绑定地址和端口 (bind)
3. 监听连接 (listen) / 接受连接 (accept)
4. send() recv()
5. 关闭连接 (close)
*/
namespace Psc::socket {
Ret<Socket_FD> create_socket_fd(Socket_Type type);
Ret<void> set_reuse(Socket_FD that, bool enable);
// 开启了一个调试模式,允许内核在网络操作中记录详细的信息。可以通过查看内核日志或tcpdump、Wireshark、strace来实际观察这些调试信息。
Ret<void> set_debug(Socket_FD that, bool enable);
Ret<void> set_block(Socket_FD that, bool blocking);
Ret<void> set_reuse_addr(Socket_FD that, bool enable);
Ret<void> set_buffer_size(Socket_FD that, size_t buffer_size);
Ret<std::vector<Socket_FD>> select_write(std::vector<Socket_FD> fds,
int timeout_ms);
Ret<std::vector<Socket_FD>> select_read(const std::vector<Socket_FD> &recv_fd_vector, int timeout_ms);
Ret<bool> select_write(Socket_FD that, int timeout_ms);
Ret<bool> select_read(Socket_FD that, int timeout_ms);
Ret<Sockaddr_In> get_addr(Socket_FD that);
Ret<Sockaddr_In> get_dest_addr(Socket_FD that);
std::string socket_base_info(Socket_FD that);
// 对于 TCP 套接字,fd 是一个已经连接的套接字(通过 connect() 或 accept()
// 获得的)。 对于 UDP 套接字,你可以使用 connect()
// 指定一个默认的目标地址(然后使用 send()),或者直接使用 sendto()
// 来指定目标地址。
// NetError::in_progress
// NetError::invalid_argument
Ret<bool> connect(Socket_FD that, const Sockaddr_In &addr);
Ret<void> close(Socket_FD that);
Ret<int> send(Socket_FD connected_fd, const std::string &data);
Ret<int> send(Socket_FD connected_fd, void* data, std::size_t size);
Ret<std::string> recv_all(Socket_FD connected_fd);
Ret<std::string> recv_once(Socket_FD fd, int chunk_size);
Ret<void> bind(Socket_FD that, const Sockaddr_In &addr);
Ret<std::string> recv_all_until_idle(Socket_FD that, int chunk_size, size_t max_bytes, int idle_timeout_ms, bool eof_is_ok );
namespace TCP {
Ret<void> set_no_delay(Socket_FD that, bool no_delay);
Ret<void> set_keep_alive(Socket_FD that, bool enable);
Ret<std::optional<Accept_Info>> accept(Socket_FD that);
Ret<void> listen(Socket_FD that, int backlog);
} // namespace TCP
namespace UDP {
Ret<int> sendto(Socket_FD that, const std::string &client_ip,
uint16_t client_port, const std::string &data);
Ret<std::string> recvfrom(Socket_FD receive_fd, Sockaddr_In *ret,
int chunk_size = 1024 * 1024);
} // namespace UDP
template <typename T> std::string Ret_To_String(const Ret<T> &r) {
auto ec = r.error();
std::ostringstream oss;
oss << "" << to_string(ec.nerr) << "】[" << "]";
if (ec.native) {
auto& nec = ec.native;
oss << " native【" << nec.category().name() << ":" << nec.value() << "】[" << Psc::platform_2_utf8(nec.message()) << "]";
}
return oss.str();
}
class Socket_Base {
public:
virtual ~Socket_Base() = default;
std::optional<Sockaddr_In> address;
Socket_FD socket_fd = -1;
virtual std::string to_string() { return address->to_string(); }
[[nodiscard]] JSON to_Json() const;
virtual void close() {
auto r = socket::close(socket_fd);
if (!r) {
socket_logger->c_debug({}, {}, to_string() + "关闭失败!");
}
socket_fd = -1;
}
};
bool is_needed_reconnect_ec(ERROR_CODE_TYPE r);
bool is_needed_reconnect(Socket_FD that);
bool is_client_need_close_ec(ERROR_CODE_TYPE r);
bool is_client_need_close(Socket_FD that);
} // namespace Psc::socket
#endif // SOCKET_H