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); version.serialize_to(version_packet.raw_data);
tcp_write(std::move(version_packet)); tcp_write(std::move(version_packet));
start_read(); start_tcp_read();
m_io.run(); 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 // maximum we can ever expect from udp
static thread_local std::vector<uint8_t> s_buffer(std::numeric_limits<uint16_t>::max()); auto ep = std::make_shared<ip::udp::endpoint>();
m_udp_socket.receive_from(buffer(s_buffer), out_ep, {}); m_udp_socket.async_receive_from(buffer(m_tmp_udp_buffer), *ep, [this, ep, handler](auto ec, auto) {
bmp::Packet packet; if (ec) {
bmp::Header header {}; spdlog::error("Failed to receive UDP from server: {}", ec.message());
auto offset = header.deserialize_from(s_buffer); } else {
packet.raw_data.resize(header.size); bmp::Packet packet;
std::copy(s_buffer.begin() + long(offset), s_buffer.begin() + long(offset) + header.size, packet.raw_data.begin()); bmp::Header header {};
return packet; 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) { 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) { tcp_read([this](auto&& packet) {
spdlog::debug("Got packet 0x{:x} from server", int(packet.purpose)); spdlog::debug("Got packet 0x{:x} from server", int(packet.purpose));
handle_packet(packet); 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(); void run();
private: 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). /// Reads a single packet from the TCP stream. Blocks all other reads (not writes).
void tcp_read(std::function<void(bmp::Packet&&)> handler); 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); 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. /// 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. /// Sends a packet to the specified UDP endpoint via the UDP socket.
void udp_write(bmp::Packet& packet); 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 // these two tmp fields are used for temporary reading into by read, don't use anywhere else please
bmp::Packet m_tmp_packet {}; bmp::Packet m_tmp_packet {};
std::vector<uint8_t> m_tmp_header_buffer {}; 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 {}; bmp::State m_state {};