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

150 lines
3.5 KiB
C++

// UDP_Server.cpp
#include "UDP_Server.h"
#include <algorithm>
namespace Psc::socket {
static bool same_endpoint(const Sockaddr_In& a, const Sockaddr_In& b) {
return a.ip == b.ip && a.port == b.port;
}
void UDP_Server::create() {
bound = false;
has_last_peer = false;
clients.clear();
auto rsf = socket::create_socket_fd(Socket_Type::UDP);
if (!rsf) {
return;
}
socket_fd = rsf.value();
state = Not_Set_Field;
// 只能非阻塞
auto r2 = socket::set_block(socket_fd, false)
.and_then([this]() { return socket::set_reuse_addr(socket_fd, true); })
.and_then([this]() { return socket::set_debug(socket_fd, true); })
.and_then([this]() { return socket::set_buffer_size(socket_fd, buffer_size); });
if (!r2) {
state = Not_Bind;
}
socket_fd = rsf.value();
}
bool UDP_Server::bind() {
if (socket_fd == -1) {
create();
if (socket_fd == -1) return false;
}
auto r = socket::bind(socket_fd, bind_address);
if (!r) {
bound = false;
return false;
}
state = Working;
bound = true;
return true;
}
// std::string UDP_Server::read() {
// if (!bound) {
// if (!bind()) return {};
// }
//
// Sockaddr_In peer{};
// auto r = socket::UDP::recvfrom(socket_fd, &peer, read_chunk_size);
// if (!r) {
// return {};
// }
//
// last_peer = peer;
// has_last_peer = true;
//
// // 收集 client:去重加入
// const bool exists =
// std::any_of(clients.begin(), clients.end(),
// [&](const Sockaddr_In& c) { return same_endpoint(c, peer); });
// if (!exists) {
// clients.push_back(peer);
// }
//
// return r.value();
// }
void UDP_Server::tick() {
if (!bound) {
if (!bind()) return;
}
Sockaddr_In peer{};
auto r = socket::UDP::recvfrom(socket_fd, &peer, read_chunk_size);
if (!r) return;
if (peer.ip == "" && peer.port == 0) return; // 不知道为什么会有这个
last_peer = peer;
has_last_peer = true;
// 连接/断开切换:存在 => 断开(移除),不存在 => 连接(加入)
auto it = std::find_if(clients.begin(), clients.end(),
[&](const Sockaddr_In& c) { return same_endpoint(c, peer); });
if (it == clients.end()) {
// 第一次:连接
clients.push_back(peer);
// 可选:你可以在这里记录事件类型
// last_event = PeerConnected;
} else {
// 第二次:断开
clients.erase(it);
// last_event = PeerDisconnected;
}
// 如果“第一次/第二次包”只是控制含义,直接不向上层返回数据:
return;
// 如果你仍想把该包内容交给上层处理,改成:
// return r.value();
}
void UDP_Server::close() {
if (socket_fd != -1) {
(void)socket::close(socket_fd);
socket_fd = -1;
state = Not_Created;
}
bound = false;
has_last_peer = false;
clients.clear();
}
void UDP_Server::reply_last_peer(const std::string& data) {
if (socket_fd == -1 || !bound || !has_last_peer) return;
(void)socket::UDP::sendto(socket_fd, last_peer.ip, last_peer.port, data);
}
void UDP_Server::send_to(const std::string& ip, uint16_t port, const std::string& data) {
if (socket_fd == -1) {
create();
if (socket_fd == -1) return;
}
if (!bound) {
if (!bind()) return;
}
(void)socket::UDP::sendto(socket_fd, ip, port, data);
}
void UDP_Server::write_to_all_clients(const std::string& msg) {
if (socket_fd == -1) return;
if (!bound) {
if (!bind()) return;
}
for (const auto& c : clients) {
(void)socket::UDP::sendto(socket_fd, c.ip, c.port, msg);
}
}
}