]> git.localhorst.tv Git - blank.git/commitdiff
tag packets withsequence numbers
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 2 Sep 2015 21:40:21 +0000 (23:40 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 2 Sep 2015 21:40:21 +0000 (23:40 +0200)
acks are already transmitted to the other side,
but they're not used yet

src/net/Connection.hpp
src/net/Packet.hpp
src/net/net.cpp

index 49e9cdac3989eee5bd7b74969bd193502c3b3abc..ade65ebd4d955939ead5a4840409c5d5bbb5db58 100644 (file)
@@ -1,8 +1,10 @@
 #ifndef BLANK_NET_CONNECTION_HPP_
 #define BLANK_NET_CONNECTION_HPP_
 
 #ifndef BLANK_NET_CONNECTION_HPP_
 #define BLANK_NET_CONNECTION_HPP_
 
+#include "Packet.hpp"
 #include "../app/IntervalTimer.hpp"
 
 #include "../app/IntervalTimer.hpp"
 
+#include <cstdint>
 #include <SDL_net.h>
 
 
 #include <SDL_net.h>
 
 
@@ -17,24 +19,27 @@ public:
 
        bool Matches(const IPaddress &) const noexcept;
 
 
        bool Matches(const IPaddress &) const noexcept;
 
-       void FlagSend() noexcept;
-       void FlagRecv() noexcept;
-
        bool ShouldPing() const noexcept;
        bool TimedOut() const noexcept;
 
        void Update(int dt);
 
        bool ShouldPing() const noexcept;
        bool TimedOut() const noexcept;
 
        void Update(int dt);
 
-
        void SendPing(UDPpacket &, UDPsocket);
 
        void Send(UDPpacket &, UDPsocket);
        void SendPing(UDPpacket &, UDPsocket);
 
        void Send(UDPpacket &, UDPsocket);
+       void Received(const UDPpacket &);
+
+private:
+       void FlagSend() noexcept;
+       void FlagRecv() noexcept;
 
 private:
        IPaddress addr;
        IntervalTimer send_timer;
        IntervalTimer recv_timer;
 
 
 private:
        IPaddress addr;
        IntervalTimer send_timer;
        IntervalTimer recv_timer;
 
+       Packet::TControl ctrl;
+
 };
 
 }
 };
 
 }
index d5479909bac38cbe6085e0e0ce4e95c1849d6c60..b7c8a5fa5aeb90d3b018cd2d791a771ff687f041 100644 (file)
@@ -16,8 +16,15 @@ struct Packet {
                LOGIN = 1,
        };
 
                LOGIN = 1,
        };
 
+       struct TControl {
+               std::uint16_t seq;
+               std::uint16_t ack;
+               std::uint32_t hist;
+       };
+
        struct Header {
                std::uint32_t tag;
        struct Header {
                std::uint32_t tag;
+               TControl ctrl;
                std::uint8_t type;
        } header;
 
                std::uint8_t type;
        } header;
 
index 20b6f5c22660d8c27b474d0d8e652369dd650bcc..314410ebbdb66fee6bb053f43a7dac6d02762dd6 100644 (file)
@@ -75,7 +75,7 @@ void Client::HandlePacket(const UDPpacket &udp_pack) {
                return;
        }
 
                return;
        }
 
-       conn.FlagRecv();
+       conn.Received(udp_pack);
        cout << "I got something!" << endl;
 }
 
        cout << "I got something!" << endl;
 }
 
@@ -102,7 +102,8 @@ void Client::SendLogin(const string &name) {
 Connection::Connection(const IPaddress &addr)
 : addr(addr)
 , send_timer(5000)
 Connection::Connection(const IPaddress &addr)
 : addr(addr)
 , send_timer(5000)
-, recv_timer(10000) {
+, recv_timer(10000)
+, ctrl{ 0, 0xFFFF, 0xFFFF } {
        send_timer.Start();
        recv_timer.Start();
 }
        send_timer.Start();
        recv_timer.Start();
 }
@@ -133,14 +134,53 @@ void Connection::Update(int dt) {
 }
 
 
 }
 
 
-void Connection::Send(UDPpacket &pack, UDPsocket sock) {
-       pack.address = addr;
-       if (SDLNet_UDP_Send(sock, -1, &pack) == 0) {
+void Connection::Send(UDPpacket &udp_pack, UDPsocket sock) {
+       Packet &pack = *reinterpret_cast<Packet *>(udp_pack.data);
+       pack.header.ctrl = ctrl;
+
+       udp_pack.address = addr;
+       if (SDLNet_UDP_Send(sock, -1, &udp_pack) == 0) {
                throw NetError("SDLNet_UDP_Send");
        }
                throw NetError("SDLNet_UDP_Send");
        }
+
        FlagSend();
 }
 
        FlagSend();
 }
 
+void Connection::Received(const UDPpacket &udp_pack) {
+       Packet &pack = *reinterpret_cast<Packet *>(udp_pack.data);
+
+       int diff = std::int16_t(pack.header.ctrl.seq) - std::int16_t(ctrl.ack);
+
+       if (diff > 0) {
+               // incoming more recent than last acked
+
+               // TODO: packets considered lost are detected here
+               //       this should have ones for all of them:
+               //       ~hist & ((1 << dist) - 1) if dist is < 32
+
+               if (diff >= 32) {
+                       // missed more than the last 32 oO
+                       ctrl.hist = 0;
+               } else {
+                       ctrl.hist >>= diff;
+                       ctrl.hist |= 1 << (32 - diff);
+               }
+       } else if (diff < 0) {
+               // incoming older than acked
+               if (diff > -32) {
+                       // too late :/
+               } else {
+                       ctrl.hist |= 1 << (32 + diff);
+               }
+       } else {
+               // incoming the same as last acked oO
+       }
+
+       ctrl.ack = pack.header.ctrl.seq;
+
+       FlagRecv();
+}
+
 void Connection::SendPing(UDPpacket &udp_pack, UDPsocket sock) {
        Packet &pack = *reinterpret_cast<Packet *>(udp_pack.data);
        udp_pack.len = pack.Ping();
 void Connection::SendPing(UDPpacket &udp_pack, UDPsocket sock) {
        Packet &pack = *reinterpret_cast<Packet *>(udp_pack.data);
        udp_pack.len = pack.Ping();
@@ -230,7 +270,7 @@ void Server::HandlePacket(const UDPpacket &udp_pack) {
        }
 
        Connection &client = GetClient(udp_pack.address);
        }
 
        Connection &client = GetClient(udp_pack.address);
-       client.FlagRecv();
+       client.Received(udp_pack);
 
        switch (pack.header.type) {
                case Packet::PING:
 
        switch (pack.header.type) {
                case Packet::PING: