22inline FluxPacket::FluxPacket(Packet
const& pck, Identity
const&
id, std::size_t fluxIndex, std::size_t fluxCount) :
25 g_timestamp(Client::getTimestamp_ms()),
26 g_fluxIndex(fluxIndex),
27 g_fluxCount(fluxCount)
29inline FluxPacket::FluxPacket(Packet&& pck, Identity
const&
id, std::size_t fluxIndex, std::size_t fluxCount) :
30 ProtocolPacket(std::move(pck)),
32 g_timestamp(Client::getTimestamp_ms()),
33 g_fluxIndex(fluxIndex),
34 g_fluxCount(fluxCount)
37inline Timestamp FluxPacket::getTimeStamp()
const
39 return this->g_timestamp;
41inline Identity
const& FluxPacket::getIdentity()
const
48template<
class TPacket>
49bool ServerSideNetUdp::start(Port bindPort, IpAddress
const& bindIp, IpAddress::Types addressType)
55 this->g_socket.setAddressType(addressType);
56 if (this->g_socket.bind(bindPort, bindIp) == Socket::ERR_NOERROR)
58 this->g_running =
true;
60 this->g_threadReception = std::make_unique<std::thread>(&ServerSideNetUdp::threadReception<TPacket>,
this);
61 this->g_threadTransmission =
62 std::make_unique<std::thread>(&ServerSideNetUdp::threadTransmission<TPacket>,
this);
68template<
class TPacket>
69bool ServerSideNetUdp::start(IpAddress::Types addressType)
75 this->g_socket.setAddressType(addressType);
76 if (this->g_socket.isValid())
78 this->g_running =
true;
80 this->g_threadReception = std::make_unique<std::thread>(&ServerSideNetUdp::threadReception<TPacket>,
this);
81 this->g_threadTransmission =
82 std::make_unique<std::thread>(&ServerSideNetUdp::threadTransmission<TPacket>,
this);
89template<
class TPacket>
90void ServerSideNetUdp::threadReception()
94 std::size_t pushingIndex = 0;
96 while (this->g_running)
98 if (this->g_socket.select(
true, 500) == Socket::ERR_NOERROR)
100 if (this->g_socket.receiveFrom(pckReceive, idReceive._ip, idReceive._port) == Socket::ERR_NOERROR)
102#ifdef FGE_ENABLE_SERVER_NETWORK_RANDOM_LOST
109 std::scoped_lock
const lck(this->g_mutexServer);
111 if (pckReceive.getDataSize() < ProtocolPacket::HeaderSize)
117 pckReceive.skip(ProtocolPacket::HeaderSize);
118 auto fluxPacket = std::make_unique<FluxPacket>(std::move(pckReceive), idReceive);
121 auto const header = fluxPacket->retrieveHeader().value();
122 if ((header & ~FGE_NET_HEADER_FLAGS_MASK) == FGE_NET_BAD_HEADERID ||
123 (header & FGE_NET_HEADER_LOCAL_REORDERED_FLAG) > 0)
130 if (this->g_fluxes.empty())
132 this->g_defaultFlux.pushPacket(std::move(fluxPacket));
137 for (std::size_t i = 0; i < this->g_fluxes.size(); ++i)
139 pushingIndex = (pushingIndex + 1) % this->g_fluxes.size();
140 fluxPacket->g_fluxIndex = pushingIndex;
141 if (this->g_fluxes[pushingIndex]->pushPacket(std::move(fluxPacket)))
151template<
class TPacket>
152void ServerSideNetUdp::threadTransmission()
154 std::unique_lock lckServer(this->g_mutexServer);
156 while (this->g_running)
158 this->g_transmissionNotifier.wait_for(lckServer, std::chrono::milliseconds(10));
161 for (std::size_t i = 0; i < this->g_fluxes.size() + 1; ++i)
163 ClientList* clients{
nullptr};
164 if (i == this->g_fluxes.size())
166 clients = &this->g_defaultFlux._clients;
170 clients = &this->g_fluxes[i]->_clients;
173 auto clientLock = clients->acquireLock();
175 for (
auto itClient = clients->begin(clientLock); itClient != clients->end(clientLock); ++itClient)
177 if (itClient->second->isPendingPacketsEmpty())
182 if (itClient->second->getLastPacketElapsedTime() < itClient->second->getSTOCLatency_ms())
187 auto transmissionPacket = itClient->second->popPacket();
189 if (!transmissionPacket->packet() || !transmissionPacket->packet().haveCorrectHeaderSize())
195 transmissionPacket->applyOptions(*itClient->second);
198 TPacket packet(transmissionPacket->packet());
199 this->g_socket.sendTo(packet, itClient->first._ip, itClient->first._port);
200 itClient->second->resetLastPacketTimePoint();
205 while (!this->g_transmissionQueue.empty())
207 auto data = std::move(this->g_transmissionQueue.front());
208 this->g_transmissionQueue.pop();
210 if (!data.first->packet() || !data.first->packet().haveCorrectHeaderSize())
216 TPacket packet(data.first->packet());
217 this->g_socket.sendTo(packet, data.second._ip, data.second._port);
224template<
class TPacket>
225bool ClientSideNetUdp::start(Port bindPort,
226 IpAddress
const& bindIp,
227 Port connectRemotePort,
228 IpAddress
const& connectRemoteAddress,
229 IpAddress::Types addressType)
235 this->g_socket.setAddressType(addressType);
236 if (this->g_socket.bind(bindPort, bindIp) == Socket::ERR_NOERROR)
238 if (this->g_socket.connect(connectRemoteAddress, connectRemotePort) == Socket::ERR_NOERROR)
240 this->g_clientIdentity._ip = connectRemoteAddress;
241 this->g_clientIdentity._port = connectRemotePort;
243 this->g_running =
true;
245 this->g_threadReception = std::make_unique<std::thread>(&ClientSideNetUdp::threadReception<TPacket>,
this);
246 this->g_threadTransmission =
247 std::make_unique<std::thread>(&ClientSideNetUdp::threadTransmission<TPacket>,
this);
252 this->g_socket.close();
256template<
class TPacket>
257void ClientSideNetUdp::threadReception()
261 while (this->g_running)
263 if (this->g_socket.select(
true, 500) == Socket::ERR_NOERROR)
265 if (this->g_socket.receive(pckReceive) == Socket::ERR_NOERROR)
267#ifdef FGE_ENABLE_CLIENT_NETWORK_RANDOM_LOST
274 if (pckReceive.getDataSize() < ProtocolPacket::HeaderSize)
280 pckReceive.skip(ProtocolPacket::HeaderSize);
281 auto fluxPacket = std::make_unique<FluxPacket>(std::move(pckReceive), this->g_clientIdentity);
284 auto const header = fluxPacket->retrieveHeader().value();
285 if ((header & ~FGE_NET_HEADER_FLAGS_MASK) == FGE_NET_BAD_HEADERID ||
286 (header & FGE_NET_HEADER_LOCAL_REORDERED_FLAG) > 0)
291 this->pushPacket(std::move(fluxPacket));
292 this->g_receptionNotifier.notify_all();
297template<
class TPacket>
298void ClientSideNetUdp::threadTransmission()
300 std::unique_lock lckServer(this->_g_mutexFlux);
302 while (this->g_running)
304 this->g_transmissionNotifier.wait_for(lckServer, std::chrono::milliseconds(10));
307 if (!this->_client.isPendingPacketsEmpty())
309 if (this->_client.getLastPacketElapsedTime() >= this->_client.getCTOSLatency_ms())
311 auto transmissionPacket = this->_client.popPacket();
313 if (!transmissionPacket->packet() || !transmissionPacket->packet().haveCorrectHeaderSize())
319 transmissionPacket->applyOptions(this->_client);
322 TPacket packet = transmissionPacket->packet();
323 this->g_socket.send(packet);
324 this->_client.resetLastPacketTimePoint();
uint16_t Timestamp
An timestamp represent modulated current time in milliseconds.
Definition C_client.hpp:49
FGE_API fge::Random< std::mt19937_64 > _random
Default random number generator instance.