class ConnectionHandler {
public:
+ ConnectionHandler();
+
+ float PacketLoss() const noexcept { return packet_loss; }
+
+ void PacketLost(std::uint16_t);
+ void PacketReceived(std::uint16_t);
+
void Handle(const UDPpacket &);
+ virtual void OnTimeout() { }
+
+private:
+ void UpdatePacketLoss() noexcept;
+
// called as soon as the remote end ack'd given packet
virtual void OnPacketReceived(std::uint16_t) { }
// called if the remote end probably didn't get given packet
virtual void OnPacketLost(std::uint16_t) { }
- virtual void OnTimeout() { }
-
-private:
virtual void On(const Packet::Ping &) { }
virtual void On(const Packet::Login &) { }
virtual void On(const Packet::Join &) { }
virtual void On(const Packet::ChunkBegin &) { }
virtual void On(const Packet::ChunkData &) { }
+private:
+ unsigned int packets_lost;
+ unsigned int packets_received;
+ float packet_loss;
+
};
}
if (diff > 0) {
for (int i = 0; i < diff; ++i) {
if (i > 32 || (i < 32 && (ctrl_in.hist & (1 << (31 - i))) == 0)) {
- Handler().OnPacketLost(ctrl_in.ack - 32 + i);
+ Handler().PacketLost(ctrl_in.ack - 32 + i);
}
}
}
// check for newly ack'd packets
for (uint16_t s = ctrl_new.AckBegin(); s != ctrl_new.AckEnd(); --s) {
if (ctrl_new.Acks(s) && !ctrl_in.Acks(s)) {
- Handler().OnPacketReceived(s);
+ Handler().PacketReceived(s);
}
}
ctrl_in = ctrl_new;
}
+ConnectionHandler::ConnectionHandler()
+: packets_lost(0)
+, packets_received(0)
+, packet_loss(0.0f) {
+
+}
+
+void ConnectionHandler::PacketLost(uint16_t seq) {
+ OnPacketLost(seq);
+ ++packets_lost;
+ UpdatePacketLoss();
+}
+
+void ConnectionHandler::PacketReceived(uint16_t seq) {
+ OnPacketReceived(seq);
+ ++packets_received;
+ UpdatePacketLoss();
+}
+
+void ConnectionHandler::UpdatePacketLoss() noexcept {
+ unsigned int packets_total = packets_lost + packets_received;
+ if (packets_total >= 256) {
+ packet_loss = float(packets_lost) / float(packets_total);
+ packets_lost = 0;
+ packets_received = 0;
+ }
+}
+
+
ostream &operator <<(ostream &out, const IPaddress &addr) {
const unsigned char *host = reinterpret_cast<const unsigned char *>(&addr.host);
out << int(host[0])