add udp read

This commit is contained in:
Lion Kortlepel 2024-03-10 14:53:30 +01:00
parent 5d56d529bc
commit 72a5e7c5b1
No known key found for this signature in database
GPG Key ID: 4322FF2B4C71259B
2 changed files with 30 additions and 14 deletions

View File

@ -48,7 +48,7 @@ void ServerNetwork::run() {
version.serialize_to(version_packet.raw_data);
tcp_write(std::move(version_packet));
start_read();
start_tcp_read();
m_io.run();
}
@ -277,16 +277,21 @@ void ServerNetwork::tcp_write(bmp::Packet&& packet, std::function<void(boost::sy
});
}
bmp::Packet ServerNetwork::udp_read(ip::udp::endpoint& out_ep) {
void ServerNetwork::udp_read(std::function<void(ip::udp::endpoint&&, bmp::Packet&&)> handler) {
// maximum we can ever expect from udp
static thread_local std::vector<uint8_t> s_buffer(std::numeric_limits<uint16_t>::max());
m_udp_socket.receive_from(buffer(s_buffer), out_ep, {});
bmp::Packet packet;
bmp::Header header {};
auto offset = header.deserialize_from(s_buffer);
packet.raw_data.resize(header.size);
std::copy(s_buffer.begin() + long(offset), s_buffer.begin() + long(offset) + header.size, packet.raw_data.begin());
return packet;
auto ep = std::make_shared<ip::udp::endpoint>();
m_udp_socket.async_receive_from(buffer(m_tmp_udp_buffer), *ep, [this, ep, handler](auto ec, auto) {
if (ec) {
spdlog::error("Failed to receive UDP from server: {}", ec.message());
} else {
bmp::Packet packet;
bmp::Header header {};
auto offset = header.deserialize_from(m_tmp_udp_buffer);
packet.raw_data.resize(header.size);
std::copy(m_tmp_udp_buffer.begin() + long(offset), m_tmp_udp_buffer.begin() + long(offset) + header.size, packet.raw_data.begin());
handler(std::move(*ep), std::move(packet));
}
});
}
void ServerNetwork::udp_write(bmp::Packet& packet) {
@ -332,10 +337,18 @@ void ServerNetwork::handle_playing(const bmp::Packet& packet) {
}
}
void ServerNetwork::start_read() {
void ServerNetwork::start_tcp_read() {
tcp_read([this](auto&& packet) {
spdlog::debug("Got packet 0x{:x} from server", int(packet.purpose));
handle_packet(packet);
start_read();
start_tcp_read();
});
}
void ServerNetwork::start_udp_read() {
udp_read([this](auto&& ep, auto&& packet) {
spdlog::debug("Got packet 0x{:x} from server via UDP", int(packet.purpose));
handle_packet(packet);
start_udp_read();
});
}

View File

@ -19,7 +19,8 @@ public:
void run();
private:
void start_read();
void start_tcp_read();
void start_udp_read();
/// Reads a single packet from the TCP stream. Blocks all other reads (not writes).
void tcp_read(std::function<void(bmp::Packet&&)> handler);
@ -27,7 +28,7 @@ private:
void tcp_write(bmp::Packet&& packet, std::function<void(boost::system::error_code)> handler = nullptr);
/// Reads a packet from the given UDP socket, returning the client's endpoint as an out-argument.
bmp::Packet udp_read(ip::udp::endpoint& out_ep);
void udp_read(std::function<void(ip::udp::endpoint&&, bmp::Packet&&)> handler);
/// Sends a packet to the specified UDP endpoint via the UDP socket.
void udp_write(bmp::Packet& packet);
@ -45,6 +46,8 @@ private:
// these two tmp fields are used for temporary reading into by read, don't use anywhere else please
bmp::Packet m_tmp_packet {};
std::vector<uint8_t> m_tmp_header_buffer {};
// this is used by udp read, don't touch
std::vector<uint8_t> m_tmp_udp_buffer { static_cast<unsigned char>(std::numeric_limits<uint16_t>::max()) };
bmp::State m_state {};