Documentation for module: Network

Former-commit-id: 0563349542b717b602d5a6eb7728bd40b2af7e1f
This commit is contained in:
Gawaboumga
2016-05-30 14:22:31 +02:00
parent 2c941827ed
commit 36c1ef1b97
25 changed files with 1368 additions and 25 deletions

View File

@@ -6,31 +6,62 @@
namespace Nz
{
/*!
* \brief Gets the last error
* \return Socket error
*/
inline SocketError AbstractSocket::GetLastError() const
{
return m_lastError;
}
/*!
* \brief Gets the internal socket handle
* \return Socket handle
*/
inline SocketHandle AbstractSocket::GetNativeHandle() const
{
return m_handle;
}
/*!
* \brief Gets the internal state
* \return Socket state
*/
inline SocketState AbstractSocket::GetState() const
{
return m_state;
}
/*!
* \brief Gets the internal type
* \return Socket type
*/
inline SocketType AbstractSocket::GetType() const
{
return m_type;
}
/*!
* \brief Checks whether the blocking is enabled
* \return true If successful
*/
inline bool AbstractSocket::IsBlockingEnabled() const
{
return m_isBlockingEnabled;
}
/*!
* \brief Updates the state of the socket
*
* \param newState Next state for the socket
*/
inline void AbstractSocket::UpdateState(SocketState newState)
{
if (m_state != newState)

View File

@@ -27,17 +27,22 @@
#ifndef NAZARA_CONFIG_NETWORK_HPP
#define NAZARA_CONFIG_NETWORK_HPP
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
/*!
* \defgroup network (NazaraNetwork) Network module
* Network/System module including classes to handle networking elements...
*/
// Utilise le MemoryManager pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes)
/// Each modification of a paramater of the module needs a recompilation of the unit
// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower)
#define NAZARA_NETWORK_MANAGE_MEMORY 0
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
// Activate the security tests based on the code (Advised for development)
#define NAZARA_NETWORK_SAFE 1
/// Chaque modification d'un paramètre ci-dessous implique une modification (souvent mineure) du code
/// Each modification of a parameter following implies a modification (often minor) of the code
/// Vérification des valeurs et types de certaines constantes
/// Checking the values and types of certain constants
#include <Nazara/Network/ConfigCheck.hpp>
#if defined(NAZARA_STATIC)

View File

@@ -7,11 +7,11 @@
#ifndef NAZARA_CONFIG_CHECK_NETWORK_HPP
#define NAZARA_CONFIG_CHECK_NETWORK_HPP
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp
/// This file is used to check the constant values defined in Config.hpp
#include <type_traits>
// On force la valeur de MANAGE_MEMORY en mode debug
// We fore the value of MANAGE_MEMORY in debug
#if defined(NAZARA_DEBUG) && !NAZARA_NETWORK_MANAGE_MEMORY
#undef NAZARA_NETWORK_MANAGE_MEMORY
#define NAZARA_NETWORK_MANAGE_MEMORY 0

View File

@@ -2,7 +2,7 @@
// This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp
// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp
// We suppose that Debug.hpp is already included, same goes for Config.hpp
#if NAZARA_NETWORK_MANAGE_MEMORY
#undef delete
#undef new

View File

@@ -9,11 +9,22 @@
namespace Nz
{
/*!
* \brief Constructs a IpAddress object by default
*/
inline IpAddress::IpAddress() :
m_isValid(false)
{
}
/*!
* \brief Constructs a IpAddress object with an IP and a port
*
* \param ip IPv4 address
* \param port Port of the IP
*/
inline IpAddress::IpAddress(const IPv4& ip, UInt16 port) :
m_ipv4(ip),
m_protocol(NetProtocol_IPv4),
@@ -22,6 +33,13 @@ namespace Nz
{
}
/*!
* \brief Constructs a IpAddress object with an IP and a port
*
* \param ip IPv6 address
* \param port Port of the IP
*/
inline IpAddress::IpAddress(const IPv6& ip, UInt16 port) :
m_ipv6(ip),
m_protocol(NetProtocol_IPv6),
@@ -30,46 +48,100 @@ namespace Nz
{
}
/*!
* \brief Constructs a IpAddress object with an IP and a port
*
* \param ip IPv4 address (a.b.c.d)
* \param port Port of the IP
*/
inline IpAddress::IpAddress(const UInt8& a, const UInt8& b, const UInt8& c, const UInt8& d, UInt16 port) :
IpAddress(IPv4{a, b, c, d}, port)
{
}
/*!
* \brief Constructs a IpAddress object with an IP and a port
*
* \param ip IPv6 address (a.b.c.d.e.f.g.h)
* \param port Port of the IP
*/
inline IpAddress::IpAddress(const UInt16& a, const UInt16& b, const UInt16& c, const UInt16& d, const UInt16& e, const UInt16& f, const UInt16& g, const UInt16& h, UInt16 port) :
IpAddress(IPv6{a, b, c, d, e, f, g, h}, port)
{
}
/*!
* Constructs a IpAddress object with a C-string
*
* \param address Hostname or textual IP address
*/
inline IpAddress::IpAddress(const char* address)
{
BuildFromAddress(address);
}
/*!
* Constructs a IpAddress object with a string
*
* \param address Hostname or textual IP address
*/
inline IpAddress::IpAddress(const String& address)
{
BuildFromAddress(address.GetConstBuffer());
}
/*!
* \brief Gets the port
* \return Port attached to the IP address
*/
inline UInt16 IpAddress::GetPort() const
{
return m_port;
}
/*!
* \brief Gets the net protocol
* \return Protocol attached to the IP address
*/
inline NetProtocol IpAddress::GetProtocol() const
{
return m_protocol;
}
/*!
* \brief Checks whether the IP address is valid
* \return true If successful
*/
inline bool IpAddress::IsValid() const
{
return m_isValid;
}
/*!
* \brief Sets the port
*
* \param port Port attached to the IP address
*/
inline void IpAddress::SetPort(UInt16 port)
{
m_port = port;
}
/*!
* \brief Converts IpAddress to IPv4
* \return Corresponding IPv4
*
* \remark Produces a NazaraAssert if net protocol is not IPv4
*/
inline IpAddress::IPv4 IpAddress::ToIPv4() const
{
NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4");
@@ -77,6 +149,13 @@ namespace Nz
return m_ipv4;
}
/*!
* \brief Converts IpAddress to IPv6
* \return Corresponding IPv6
*
* \remark Produces a NazaraAssert if net protocol is not IPv6
*/
inline IpAddress::IPv6 IpAddress::ToIPv6() const
{
NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv6, "IP is not a valid IPv6");
@@ -84,6 +163,13 @@ namespace Nz
return m_ipv6;
}
/*!
* \brief Converts IpAddress to UInt32
* \return Corresponding UInt32
*
* \remark Produces a NazaraAssert if net protocol is not IPv4
*/
inline UInt32 IpAddress::ToUInt32() const
{
NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4");
@@ -94,17 +180,40 @@ namespace Nz
UInt32(m_ipv4[3]) << 0;
}
/*!
* \brief Converts IpAddress to boolean
* \return true If IpAddress is valid
*
* \see IsValid
*/
inline IpAddress::operator bool() const
{
return IsValid();
}
/*!
* \brief Output operator
* \return The stream
*
* \param out The stream
* \param address The address to output
*/
inline std::ostream& operator<<(std::ostream& out, const IpAddress& address)
{
out << "IpAddress(" << address.ToString() << ')';
return out;
}
/*!
* \brief Compares the IpAddress to other one
* \return true if the ip addresses are the same
*
* \param first First ip address to compare
* \param second Second ip address to compare with
*/
inline bool operator==(const IpAddress& first, const IpAddress& second)
{
// We need to check the validity of each address before comparing them
@@ -146,11 +255,27 @@ namespace Nz
return true;
}
/*!
* \brief Compares the IpAddress to other one
* \return false if the ip addresses are the same
*
* \param first First ip address to compare
* \param second Second ip address to compare with
*/
inline bool operator!=(const IpAddress& first, const IpAddress& second)
{
return !operator==(first, second);
}
/*!
* \brief Compares the IpAddress to other one
* \return true if this ip address is inferior to the other one
*
* \param first First ip address to compare
* \param second Second ip address to compare with
*/
inline bool operator<(const IpAddress& first, const IpAddress& second)
{
// If the second address is invalid, there's no way we're lower than it
@@ -196,16 +321,40 @@ namespace Nz
return false; //< Same address
}
/*!
* \brief Compares the IpAddress to other one
* \return true if this ip address is inferior or equal to the other one
*
* \param first First ip address to compare
* \param second Second ip address to compare with
*/
inline bool operator<=(const IpAddress& first, const IpAddress& second)
{
return !operator<(second, first);
}
/*!
* \brief Compares the IpAddress to other one
* \return true if this ip address is greather to the other one
*
* \param first First ip address to compare
* \param second Second ip address to compare with
*/
inline bool operator>(const IpAddress& first, const IpAddress& second)
{
return second < first;
}
/*!
* \brief Compares the IpAddress to other one
* \return true if this ip address is greather or equal to the other one
*
* \param first First ip address to compare
* \param second Second ip address to compare with
*/
inline bool operator>=(const IpAddress& first, const IpAddress& second)
{
return !operator<(first, second);
@@ -217,6 +366,13 @@ namespace std
template<>
struct hash<Nz::IpAddress>
{
/*!
* \brief Converts IpAddress to hash
* \return Hash of the IpAddress
*
* \param ip IpAddress to hash
*/
size_t operator()(const Nz::IpAddress& ip) const
{
if (!ip)
@@ -224,7 +380,7 @@ namespace std
// This is SDBM adapted for IP addresses, tested to generate the least collisions possible
// (It doesn't mean it cannot be improved though)
std::size_t h = 0;
std::size_t hash = 0;
switch (ip.GetProtocol())
{
case Nz::NetProtocol_Any:
@@ -233,20 +389,20 @@ namespace std
case Nz::NetProtocol_IPv4:
{
h = ip.ToUInt32() + (h << 6) + (h << 16) - h;
hash = ip.ToUInt32() + (hash << 6) + (hash << 16) - hash;
break;
}
case Nz::NetProtocol_IPv6:
{
Nz::IpAddress::IPv6 v6 = ip.ToIPv6();
for (std::size_t i = 0; i < v6.size(); i++)
h = v6[i] + (h << 6) + (h << 16) - h;
hash = v6[i] + (hash << 6) + (hash << 16) - hash;
break;
}
}
return ip.GetPort() + (h << 6) + (h << 16) - h;
return ip.GetPort() + (hash << 6) + (hash << 16) - hash;
}
};
}

View File

@@ -9,21 +9,46 @@
namespace Nz
{
/*!
* \brief Constructs a NetPacket object by default
*/
inline NetPacket::NetPacket() :
m_netCode(NetCode_Invalid)
{
}
/*!
* \brief Constructs a NetPacket object with a packet number and a minimal capacity
*
* \param netCode Packet number
* \param minCapacity Minimal capacity of the packet
*/
inline NetPacket::NetPacket(UInt16 netCode, std::size_t minCapacity)
{
Reset(netCode, minCapacity);
}
/*!
* \brief Constructs a NetPacket object with a packet number and raw memory
*
* \param netCode Packet number
* \param ptr Raw memory
* \param size Size of the memory
*/
inline NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size)
{
Reset(netCode, ptr, size);
}
/*!
* \brief Constructs a NetPacket object with another one by move semantic
*
* \param packet NetPacket to move into this
*/
inline NetPacket::NetPacket(NetPacket&& packet) :
ByteStream(std::move(packet)),
m_buffer(std::move(packet.m_buffer)),
@@ -35,12 +60,23 @@ namespace Nz
SetStream(&m_memoryStream);
}
/*!
* \brief Destructs the object
*/
inline NetPacket::~NetPacket()
{
FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it
FreeStream();
}
/*!
* \brief Gets the raw buffer
* \return Constant raw buffer
*
* \remark Produces a NazaraAssert if internal buffer is invalid
*/
inline const UInt8* NetPacket::GetConstData() const
{
NazaraAssert(m_buffer, "Invalid buffer");
@@ -48,6 +84,13 @@ namespace Nz
return m_buffer->GetConstBuffer();
}
/*!
* \brief Gets the raw buffer
* \return Raw buffer
*
* \remark Produces a NazaraAssert if internal buffer is invalid
*/
inline UInt8* NetPacket::GetData() const
{
NazaraAssert(m_buffer, "Invalid buffer");
@@ -55,6 +98,11 @@ namespace Nz
return m_buffer->GetBuffer();
}
/*!
* \brief Gets the size of the data
* \return Size of the data
*/
inline size_t NetPacket::GetDataSize() const
{
if (m_buffer)
@@ -63,22 +111,46 @@ namespace Nz
return 0;
}
/*!
* \brief Gets the packet number
* \return Packet number
*/
inline UInt16 NetPacket::GetNetCode() const
{
return m_netCode;
}
/*!
* \brief Resets the packet
*/
inline void NetPacket::Reset()
{
FreeStream();
}
/*!
* \brief Resets the packet with a packet number and a minimal capacity
*
* \param netCode Packet number
* \param minCapacity Minimal capacity of the packet
*/
inline void NetPacket::Reset(UInt16 netCode, std::size_t minCapacity)
{
InitStream(HeaderSize + minCapacity, HeaderSize, OpenMode_ReadWrite);
m_netCode = netCode;
}
/*!
* \brief Resets the packet with a packet number and raw memory
*
* \param netCode Packet number
* \param ptr Raw memory
* \param size Size of the memory
*/
inline void NetPacket::Reset(UInt16 netCode, const void* ptr, std::size_t size)
{
InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly);
@@ -88,6 +160,14 @@ namespace Nz
m_netCode = netCode;
}
/*!
* \brief Resizes the packet
*
* \param newSize Size for the resizing operation
*
* \remark Produces a NazaraAssert if internal buffer is invalid
*/
inline void NetPacket::Resize(std::size_t newSize)
{
NazaraAssert(m_buffer, "Invalid buffer");
@@ -95,11 +175,24 @@ namespace Nz
m_buffer->Resize(newSize);
}
/*!
* \brief Sets the packet number
*
* \param netCode Packet number
*/
inline void NetPacket::SetNetCode(UInt16 netCode)
{
m_netCode = netCode;
}
/*!
* \brief Moves the NetPacket into this
* \return A reference to this
*
* \param packet NetPacket to move in this
*/
inline NetPacket& Nz::NetPacket::operator=(NetPacket&& packet)
{
FreeStream();

View File

@@ -8,31 +8,66 @@
namespace Nz
{
/*!
* \brief Closes the connection
*/
inline void RUdpConnection::Close()
{
m_socket.Close();
}
/*!
* \brief Disconnects the connection
*
* \see Close
*/
inline void RUdpConnection::Disconnect()
{
Close();
}
/*!
* \brief Gets the bound address
* \return IpAddress we are linked to
*/
inline IpAddress RUdpConnection::GetBoundAddress() const
{
return m_socket.GetBoundAddress();
}
/*!
* \brief Gets the port of the bound address
* \return Port we are linked to
*/
inline UInt16 RUdpConnection::GetBoundPort() const
{
return m_socket.GetBoundPort();
}
/*!
* \brief Gets the last error
* \return Socket error
*/
inline SocketError RUdpConnection::GetLastError() const
{
return m_lastError;
}
/*!
* \brief Listens to a socket
* \return true If successfully bound
*
* \param protocol Net protocol to listen to
* \param port Port to listen to
*
* \remark Produces a NazaraAssert if protocol is unknown or any
*/
inline bool RUdpConnection::Listen(NetProtocol protocol, UInt16 port)
{
NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO
@@ -59,16 +94,36 @@ namespace Nz
return Listen(any);
}
/*!
* \brief Sets the protocol id
*
* \param protocolId Protocol ID like NNet
*/
inline void RUdpConnection::SetProtocolId(UInt32 protocolId)
{
m_protocol = protocolId;
}
/*!
* \brief Sets the time before ack
*
* \param Time before acking to send many together (in ms)
*/
inline void RUdpConnection::SetTimeBeforeAck(UInt32 ms)
{
m_forceAckSendTime = ms * 1000; //< Store in microseconds for easier handling
}
/*!
* \brief Computes the difference of sequence
* \return Delta between the two sequences
*
* \param sequence First sequence
* \param sequence2 Second sequence
*/
inline unsigned int RUdpConnection::ComputeSequenceDifference(SequenceIndex sequence, SequenceIndex sequence2)
{
unsigned int difference;
@@ -80,6 +135,13 @@ namespace Nz
return 0;
}
/*!
* \brief Checks whether the peer has pending packets
* \return true If it is the case
*
* \param peer Data relative to the peer
*/
inline bool RUdpConnection::HasPendingPackets(PeerData& peer)
{
for (unsigned int priority = PacketPriority_Highest; priority <= PacketPriority_Lowest; ++priority)
@@ -94,6 +156,14 @@ namespace Nz
return false;
}
/*!
* \brief Checks whether the ack is more recent
* \return true If it is the case
*
* \param ack First sequence
* \param ack2 Second sequence
*/
inline bool RUdpConnection::IsAckMoreRecent(SequenceIndex ack, SequenceIndex ack2)
{
constexpr SequenceIndex maxDifference = std::numeric_limits<SequenceIndex>::max() / 2;
@@ -106,6 +176,13 @@ namespace Nz
return false; ///< Same ack
}
/*!
* \brief Checks whether the connection is reliable
* \return true If it is the case
*
* \remark Produces a NazaraError if enumeration is invalid
*/
inline bool RUdpConnection::IsReliable(PacketReliability reliability)
{
switch (reliability)
@@ -122,6 +199,14 @@ namespace Nz
return false;
}
/*!
* \brief Simulates the loss of packets on network
*
* \param packetLoss Ratio of packet loss according to bernoulli distribution
*
* \remark Produces a NazaraAssert if packetLoss is not in between 0.0 and 1.0
*/
inline void RUdpConnection::SimulateNetwork(double packetLoss)
{
NazaraAssert(packetLoss >= 0.0 && packetLoss <= 1.0, "Packet loss must be in range [0..1]");

View File

@@ -79,8 +79,8 @@ namespace Nz
PendingPacket m_pendingPacket;
UInt64 m_keepAliveInterval;
UInt64 m_keepAliveTime;
bool m_isKeepAliveEnabled;
bool m_isLowDelayEnabled;
bool m_isKeepAliveEnabled;
};
}

View File

@@ -7,6 +7,10 @@
namespace Nz
{
/*!
* \brief Constructs a TcpClient object by default
*/
inline TcpClient::TcpClient() :
AbstractSocket(SocketType_TCP),
Stream(StreamOption_Sequential),
@@ -17,31 +21,62 @@ namespace Nz
{
}
/*!
* \brief Disconnects the connection
*
* \see Close
*/
inline void TcpClient::Disconnect()
{
Close();
}
/*!
* \brief Gets the interval between two keep alive pings
* \return Interval in milliseconds between two pings
*/
inline UInt64 TcpClient::GetKeepAliveInterval() const
{
return m_keepAliveInterval;
}
/*!
* \brief Gets the time before expiration of connection
* \return Time in milliseconds before expiration
*/
inline UInt64 TcpClient::GetKeepAliveTime() const
{
return m_keepAliveTime;
}
/*!
* \brief Gets the remote address
* \return Address of peer
*/
inline IpAddress TcpClient::GetRemoteAddress() const
{
return m_peerAddress;
}
/*!
* \brief Checks whether low delay is enabled
* \return true If it is the case
*/
inline bool TcpClient::IsLowDelayEnabled() const
{
return m_isLowDelayEnabled;
}
/*!
* \brief Checks whether the keep alive flag is enabled
* \return true If it is the case
*/
inline bool TcpClient::IsKeepAliveEnabled() const
{
return m_isKeepAliveEnabled;

View File

@@ -7,27 +7,58 @@
namespace Nz
{
/*!
* \brief Constructs a TcpServer object by default
*/
inline TcpServer::TcpServer() :
AbstractSocket(SocketType_TCP)
{
}
/*!
* \brief Constructs a TcpServer object with another one by move semantic
*
* \param tcpServer TcpServer to move into this
*/
inline TcpServer::TcpServer(TcpServer&& tcpServer) :
AbstractSocket(std::move(tcpServer)),
m_boundAddress(std::move(tcpServer.m_boundAddress))
{
}
/*!
* \brief Gets the bound address
* \return IpAddress we are linked to
*/
inline IpAddress TcpServer::GetBoundAddress() const
{
return m_boundAddress;
}
/*!
* \brief Gets the port of the bound address
* \return Port we are linked to
*/
inline UInt16 TcpServer::GetBoundPort() const
{
return m_boundAddress.GetPort();
}
/*!
* \brief Listens to a socket
* \return State of the socket
*
* \param protocol Net protocol to listen to
* \param port Port to listen to
* \param queueSize Size of the queue
*
* \remark Produces a NazaraAssert if protocol is unknown or any
*/
inline SocketState TcpServer::Listen(NetProtocol protocol, UInt16 port, unsigned int queueSize)
{
NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO

View File

@@ -49,7 +49,6 @@ namespace Nz
void OnOpened() override;
IpAddress m_boundAddress;
SocketState m_state;
bool m_isBroadCastingEnabled;
};
}

View File

@@ -6,24 +6,46 @@
namespace Nz
{
/*!
* \brief Constructs a UdpSocket object by default
*/
inline UdpSocket::UdpSocket() :
AbstractSocket(SocketType_UDP)
{
}
/*!
* \brief Constructs a UdpSocket object with a net protocol
*
* \param protocol Net protocol to use
*/
inline UdpSocket::UdpSocket(NetProtocol protocol) :
UdpSocket()
{
Create(protocol);
}
/*!
* \brief Constructs a UdpSocket object with another one by move semantic
*
* \param udpSocket UdpSocket to move into this
*/
inline UdpSocket::UdpSocket(UdpSocket&& udpSocket) :
AbstractSocket(std::move(udpSocket)),
m_boundAddress(std::move(udpSocket.m_boundAddress)),
m_state(udpSocket.m_state)
m_boundAddress(std::move(udpSocket.m_boundAddress))
{
}
/*!
* \brief Binds a specific port
* \return State of the socket
*
* \param port Port to bind
*/
inline SocketState UdpSocket::Bind(UInt16 port)
{
IpAddress any;
@@ -47,6 +69,13 @@ namespace Nz
return Bind(any);
}
/*!
* \brief Creates a UDP socket
* \return true If successful
*
* \param protocol Net protocol to use
*/
bool UdpSocket::Create(NetProtocol protocol)
{
NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol");
@@ -54,21 +83,41 @@ namespace Nz
return Open(protocol);
}
/*!
* \brief Gets the bound address
* \return IpAddress we are linked to
*/
inline IpAddress UdpSocket::GetBoundAddress() const
{
return m_boundAddress;
}
/*!
* \brief Gets the port of the bound address
* \return Port we are linked to
*/
inline UInt16 UdpSocket::GetBoundPort() const
{
return m_boundAddress.GetPort();
}
/*!
* \brief Gets the state of the socket
* \return State of the socket
*/
inline SocketState UdpSocket::GetState() const
{
return m_state;
}
/*!
* \brief Checks whether the broadcasting is enabled
* \return true If it is the case
*/
inline bool UdpSocket::IsBroadcastingEnabled() const
{
return m_isBroadCastingEnabled;