More impl: rtt and timepoint per sent pkt
This commit is contained in:
parent
0065928422
commit
7482fecb37
3 changed files with 87 additions and 18 deletions
|
@ -7,6 +7,7 @@
|
|||
#define UDPC_BAD_MODE_SEND_INTERVAL (1.0f / 10.0f)
|
||||
#define UDPC_SENT_PKTS_MAX_SIZE 33
|
||||
#define UDPC_QUEUED_PKTS_MAX_SIZE 32
|
||||
#define UDPC_GOOD_RTT_LIMIT_SEC 0.25f
|
||||
|
||||
#define UDPC_ID_CONNECT 0x80000000
|
||||
#define UDPC_ID_PING 0x40000000
|
||||
|
@ -19,7 +20,9 @@
|
|||
#include <cstdint>
|
||||
#include <deque>
|
||||
#include <unordered_map>
|
||||
#include <queue>
|
||||
#include <random>
|
||||
#include <memory>
|
||||
|
||||
#include "TSQueue.hpp"
|
||||
#include "UDPConnection.h"
|
||||
|
@ -31,8 +34,18 @@ static const auto INIT_PKT_INTERVAL_DT = std::chrono::seconds(5);
|
|||
static const auto HEARTBEAT_PKT_INTERVAL_DT = std::chrono::milliseconds(150);
|
||||
static const auto PACKET_TIMEOUT_TIME = std::chrono::seconds(1);
|
||||
|
||||
// forward declaration
|
||||
struct Context;
|
||||
|
||||
struct SentPktInfo {
|
||||
typedef std::shared_ptr<SentPktInfo> Ptr;
|
||||
|
||||
SentPktInfo();
|
||||
|
||||
uint32_t id;
|
||||
std::chrono::steady_clock::time_point sentTime;
|
||||
};
|
||||
|
||||
struct ConnectionData {
|
||||
ConnectionData();
|
||||
ConnectionData(bool isServer, Context *ctx);
|
||||
|
@ -45,6 +58,8 @@ struct ConnectionData {
|
|||
ConnectionData(ConnectionData&& other) = default;
|
||||
ConnectionData& operator=(ConnectionData&& other) = default;
|
||||
|
||||
void cleanupSentPkts();
|
||||
|
||||
/*
|
||||
* 0 - trigger send
|
||||
* 1 - is good mode
|
||||
|
@ -66,6 +81,8 @@ struct ConnectionData {
|
|||
std::deque<UDPC_PacketInfo> sentPkts;
|
||||
TSQueue<UDPC_PacketInfo> sendPkts;
|
||||
TSQueue<UDPC_PacketInfo> priorityPkts;
|
||||
// pkt id to pkt shared_ptr
|
||||
std::unordered_map<uint32_t, SentPktInfo::Ptr> sentInfoMap;
|
||||
std::chrono::steady_clock::time_point received;
|
||||
std::chrono::steady_clock::time_point sent;
|
||||
float rtt;
|
||||
|
@ -116,6 +133,10 @@ void preparePacket(char *data, uint32_t protocolID, uint32_t conID,
|
|||
|
||||
uint32_t generateConnectionID(Context &ctx);
|
||||
|
||||
float durationToFSec(
|
||||
const std::chrono::steady_clock::time_point& older,
|
||||
const std::chrono::steady_clock::time_point& newer);
|
||||
|
||||
} // namespace UDPC
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
UDPC::SentPktInfo::SentPktInfo() :
|
||||
id(0),
|
||||
sentTime(std::chrono::steady_clock::now())
|
||||
{}
|
||||
|
||||
UDPC::ConnectionData::ConnectionData() :
|
||||
flags(),
|
||||
timer(0.0f),
|
||||
|
@ -33,6 +38,15 @@ UDPC::ConnectionData::ConnectionData()
|
|||
}
|
||||
}
|
||||
|
||||
void UDPC::ConnectionData::cleanupSentPkts() {
|
||||
uint32_t id;
|
||||
while(sentPkts.size() > UDPC_SENT_PKTS_MAX_SIZE) {
|
||||
id = *((uint32_t*)(sentPkts.front().data + 8));
|
||||
sentInfoMap.erase(id);
|
||||
sentPkts.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
UDPC::Context::Context(bool isThreaded)
|
||||
: _contextIdentifier(UDPC_CONTEXT_IDENTIFIER), flags(),
|
||||
isAcceptNewConnections(true), protocolID(UDPC_DEFAULT_PROTOCOL_ID),
|
||||
|
@ -122,6 +136,14 @@ uint32_t UDPC::generateConnectionID(Context &ctx) {
|
|||
return id;
|
||||
}
|
||||
|
||||
float UDPC::durationToFSec(
|
||||
const std::chrono::steady_clock::time_point& older,
|
||||
const std::chrono::steady_clock::time_point& newer) {
|
||||
const auto dt = newer - older;
|
||||
return (float)dt.count()
|
||||
* (float)decltype(dt)::period::num / (float)decltype(dt)::period::den;
|
||||
}
|
||||
|
||||
void *UDPC_init(uint16_t listenPort, uint32_t listenAddr, int isClient) {
|
||||
UDPC::Context *ctx = new UDPC::Context(false);
|
||||
|
||||
|
@ -200,21 +222,16 @@ void UDPC_update(void *ctx) {
|
|||
return;
|
||||
}
|
||||
|
||||
const auto prevNow = std::move(c->lastUpdated);
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
const auto dt = now - c->lastUpdated;
|
||||
const float dt_fs = (float)dt.count() * (float)decltype(dt)::period::num /
|
||||
(float)decltype(dt)::period::den;
|
||||
c->lastUpdated = now;
|
||||
|
||||
std::chrono::steady_clock::duration temp_dt;
|
||||
float temp_dt_fs;
|
||||
{
|
||||
// check timed out, check good/bad mode with rtt, remove timed out
|
||||
std::vector<uint32_t> removed;
|
||||
for(auto iter = c->conMap.begin(); iter != c->conMap.end(); ++iter) {
|
||||
temp_dt = now - iter->second.received;
|
||||
temp_dt_fs = (float)temp_dt.count() *
|
||||
(float)decltype(temp_dt)::period::num /
|
||||
(float)decltype(temp_dt)::period::den;
|
||||
temp_dt_fs = UDPC::durationToFSec(iter->second.received, now);
|
||||
if(temp_dt_fs >= UDPC_TIMEOUT_SECONDS) {
|
||||
removed.push_back(iter->first);
|
||||
continue;
|
||||
|
@ -384,11 +401,15 @@ void UDPC_update(void *ctx) {
|
|||
pInfo.receiver = iter->first;
|
||||
pInfo.senderPort = c->socketInfo.sin_port;
|
||||
pInfo.receiverPort = iter->second.port;
|
||||
*((uint32_t*)(pInfo.data + 8)) = iter->second.lseq - 1;
|
||||
|
||||
iter->second.sentPkts.push_back(std::move(pInfo));
|
||||
while(iter->second.sentPkts.size() > UDPC_SENT_PKTS_MAX_SIZE) {
|
||||
iter->second.sentPkts.pop_front();
|
||||
}
|
||||
iter->second.cleanupSentPkts();
|
||||
|
||||
// store other pkt info
|
||||
UDPC::SentPktInfo::Ptr sentPktInfo = std::make_shared<UDPC::SentPktInfo>();
|
||||
sentPktInfo->id = iter->second.lseq - 1;
|
||||
iter->second.sentInfoMap.insert(std::make_pair(sentPktInfo->id, sentPktInfo));
|
||||
} else {
|
||||
// sendPkts or priorityPkts not empty
|
||||
UDPC_PacketInfo pInfo;
|
||||
|
@ -440,11 +461,9 @@ void UDPC_update(void *ctx) {
|
|||
sentPInfo.receiverPort = iter->second.port;
|
||||
|
||||
iter->second.sentPkts.push_back(std::move(pInfo));
|
||||
while(iter->second.sentPkts.size() > UDPC_SENT_PKTS_MAX_SIZE) {
|
||||
iter->second.sentPkts.pop_front();
|
||||
}
|
||||
iter->second.cleanupSentPkts();
|
||||
} else {
|
||||
// is not check-received, no data stored but other data is kept
|
||||
// is not check-received, only id stored in data array
|
||||
UDPC_PacketInfo sentPInfo;
|
||||
sentPInfo.flags = 0x4;
|
||||
sentPInfo.dataSize = 0;
|
||||
|
@ -452,12 +471,16 @@ void UDPC_update(void *ctx) {
|
|||
sentPInfo.receiver = iter->first;
|
||||
sentPInfo.senderPort = c->socketInfo.sin_port;
|
||||
sentPInfo.receiverPort = iter->second.port;
|
||||
*((uint32_t*)(sentPInfo.data + 8)) = iter->second.lseq - 1;
|
||||
|
||||
iter->second.sentPkts.push_back(std::move(pInfo));
|
||||
while(iter->second.sentPkts.size() > UDPC_SENT_PKTS_MAX_SIZE) {
|
||||
iter->second.sentPkts.pop_front();
|
||||
}
|
||||
iter->second.cleanupSentPkts();
|
||||
}
|
||||
|
||||
// store other pkt info
|
||||
UDPC::SentPktInfo::Ptr sentPktInfo = std::make_shared<UDPC::SentPktInfo>();
|
||||
sentPktInfo->id = iter->second.lseq - 1;
|
||||
iter->second.sentInfoMap.insert(std::make_pair(sentPktInfo->id, sentPktInfo));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -541,6 +564,30 @@ void UDPC_update(void *ctx) {
|
|||
// packet is valid
|
||||
// TODO log received valid packet
|
||||
|
||||
// update rtt
|
||||
for(auto sentIter = iter->second.sentPkts.rbegin(); sentIter != iter->second.sentPkts.rend(); ++sentIter) {
|
||||
uint32_t id = *((uint32_t*)(sentIter->data + 8));
|
||||
if(id == rseq) {
|
||||
auto sentInfoIter = iter->second.sentInfoMap.find(id);
|
||||
assert(sentInfoIter != iter->second.sentInfoMap.end()
|
||||
&& "sentInfoMap should have known stored id");
|
||||
float diff = UDPC::durationToFSec(sentInfoIter->second->sentTime, now);
|
||||
if(diff > iter->second.rtt) {
|
||||
iter->second.rtt += (diff - iter->second.rtt) / 10.0f;
|
||||
} else {
|
||||
iter->second.rtt -= (iter->second.rtt - diff) / 10.0f;
|
||||
}
|
||||
|
||||
iter->second.flags.set(2, iter->second.rtt <= UDPC_GOOD_RTT_LIMIT_SEC);
|
||||
|
||||
// TODO verbose log rtt
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iter->second.received = now;
|
||||
// TODO impl check pkt timeout
|
||||
|
||||
// TODO impl
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ extern "C" {
|
|||
typedef enum { SILENT, ERROR, WARNING, VERBOSE, INFO } UDPC_LoggingType;
|
||||
|
||||
typedef struct {
|
||||
// id is stored at offset 8, size 4 (uint32_t) even for "empty" PktInfos
|
||||
char data[UDPC_PACKET_MAX_SIZE];
|
||||
/*
|
||||
* 0x1 - connect
|
||||
|
|
Loading…
Reference in a new issue