diff --git a/include/Nazara/Network/UdpSocket.hpp b/include/Nazara/Network/UdpSocket.hpp index 4730f4793..e6577bec7 100644 --- a/include/Nazara/Network/UdpSocket.hpp +++ b/include/Nazara/Network/UdpSocket.hpp @@ -26,10 +26,14 @@ namespace Nz inline bool Create(NetProtocol protocol); + void EnableBroadcasting(bool broadcasting); + inline IpAddress GetBoundAddress() const; inline UInt16 GetBoundPort() const; inline SocketState GetState() const; + inline bool IsBroadcastingEnabled() const; + unsigned int QueryMaxDatagramSize(); bool Receive(void* buffer, std::size_t size, IpAddress* from, std::size_t* received); @@ -42,6 +46,7 @@ namespace Nz IpAddress m_boundAddress; SocketState m_state; + bool m_isBroadCastingEnabled; }; } diff --git a/include/Nazara/Network/UdpSocket.inl b/include/Nazara/Network/UdpSocket.inl index fbfe7f6ab..4a75da130 100644 --- a/include/Nazara/Network/UdpSocket.inl +++ b/include/Nazara/Network/UdpSocket.inl @@ -65,6 +65,11 @@ namespace Nz { return m_state; } + + inline bool UdpSocket::IsBroadcastingEnabled() const + { + return m_isBroadCastingEnabled; + } } #include diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 22d93c08e..c668058a4 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -34,8 +34,7 @@ namespace Nz } SocketState state = SocketImpl::Connect(m_handle, remoteAddress, &m_lastError); - if (state != SocketState_NotConnected) - m_peerAddress = remoteAddress; + m_peerAddress = (state != SocketState_NotConnected) ? remoteAddress : IpAddress::Invalid; UpdateState(state); return state; @@ -75,7 +74,7 @@ namespace Nz if (m_isLowDelayEnabled != lowDelay) { - SocketImpl::SetBlocking(m_handle, lowDelay, &m_lastError); + SocketImpl::SetNoDelay(m_handle, lowDelay, &m_lastError); m_isLowDelayEnabled = lowDelay; } } @@ -109,7 +108,7 @@ namespace Nz if (error == SocketError_NoError) { - // No error yet, we're still connecting or connected, check that by connecting again + // No error yet, we're still connecting or connected, check that by calling Connect again return Connect(m_peerAddress); } else @@ -242,12 +241,12 @@ namespace Nz SocketState newState = SocketImpl::Connect(m_handle, m_peerAddress, msTimeout, &m_lastError); NazaraAssert(newState != SocketState_Connecting, "Invalid internal return"); - // Prevent valid peer adddress in non-connected state + // Prevent valid peer address in non-connected state if (newState == SocketState_NotConnected) m_peerAddress = IpAddress::Invalid; UpdateState(newState); - return m_state == SocketState_Connected; + return newState == SocketState_Connected; } case SocketState_NotConnected: diff --git a/src/Nazara/Network/UdpSocket.cpp b/src/Nazara/Network/UdpSocket.cpp index b73ef8da2..6bece4f28 100644 --- a/src/Nazara/Network/UdpSocket.cpp +++ b/src/Nazara/Network/UdpSocket.cpp @@ -26,6 +26,17 @@ namespace Nz return state; } + void UdpSocket::EnableBroadcasting(bool broadcasting) + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); + + if (m_isBroadCastingEnabled != broadcasting) + { + SocketImpl::SetBroadcasting(m_handle, broadcasting, &m_lastError); + m_isBroadCastingEnabled = broadcasting; + } + } + unsigned int UdpSocket::QueryMaxDatagramSize() { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket hasn't been created"); @@ -73,6 +84,7 @@ namespace Nz void UdpSocket::OnOpened() { m_boundAddress = IpAddress::Invalid; + m_isBroadCastingEnabled = false; UpdateState(SocketState_NotConnected); } diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 83ffaf55c..5e1834e6b 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -509,6 +509,25 @@ namespace Nz return true; } + + bool SocketImpl::SetBroadcasting(SocketHandle handle, bool broadcasting, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + BOOL option = broadcasting; + if (setsockopt(handle, SOL_SOCKET, SO_BROADCAST, reinterpret_cast(&option), sizeof(option)) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } bool SocketImpl::SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error) { @@ -534,6 +553,25 @@ namespace Nz return true; } + bool SocketImpl::SetNoDelay(SocketHandle handle, bool nodelay, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + BOOL option = nodelay; + if (setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&option), sizeof(option)) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } + SocketError SocketImpl::TranslateWSAErrorToSocketError(int error) { switch (error) diff --git a/src/Nazara/Network/Win32/SocketImpl.hpp b/src/Nazara/Network/Win32/SocketImpl.hpp index 9eb2c11ff..ad58c76f0 100644 --- a/src/Nazara/Network/Win32/SocketImpl.hpp +++ b/src/Nazara/Network/Win32/SocketImpl.hpp @@ -47,7 +47,9 @@ namespace Nz static bool SendTo(SocketHandle handle, const void* buffer, int length, const IpAddress& to, int* sent, SocketError* error); static bool SetBlocking(SocketHandle handle, bool blocking, SocketError* error = nullptr); + static bool SetBroadcasting(SocketHandle handle, bool broadcasting, SocketError* error = nullptr); static bool SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error = nullptr); + static bool SetNoDelay(SocketHandle handle, bool nodelay, SocketError* error = nullptr); static SocketError TranslateWSAErrorToSocketError(int error); static int TranslateNetProtocolToAF(NetProtocol protocol);