From fd09cdbf1e83f9aabd9976748ecbd587c2f30502 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 13:55:42 +0100 Subject: [PATCH] Network/TcpClient: Replace Connect overload by WaitForConnected method Former-commit-id: 11ff81ea975f79a51f6342a9a574a23d18c0180f --- include/Nazara/Network/TcpClient.hpp | 4 +- src/Nazara/Network/TcpClient.cpp | 57 ++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index c3b0ccc00..cd7f1dc16 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -23,7 +23,7 @@ namespace Nz inline TcpClient(TcpClient&& tcpClient); ~TcpClient() = default; - SocketState Connect(const IpAddress& remoteAddress, UInt64 msTimeout = 3000); + SocketState Connect(const IpAddress& remoteAddress); inline void Disconnect(); void EnableLowDelay(bool lowDelay); @@ -42,6 +42,8 @@ namespace Nz bool Send(const void* buffer, std::size_t size, std::size_t* sent); + bool WaitForConnected(UInt64 msTimeout = 3000); + private: void OnClose() override; void OnOpened() override; diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 583c50f44..14d06ac97 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -16,7 +16,7 @@ namespace Nz { - SocketState TcpClient::Connect(const IpAddress& remoteAddress, UInt64 msTimeout) + SocketState TcpClient::Connect(const IpAddress& remoteAddress) { NazaraAssert(remoteAddress.IsValid(), "Invalid remote address"); NazaraAssert(remoteAddress.GetPort() != 0, "Remote address has no port"); @@ -33,12 +33,7 @@ namespace Nz }); } - SocketState state; - if (msTimeout > 0) - state = SocketImpl::Connect(m_handle, remoteAddress, msTimeout, &m_lastError); - else - state = SocketImpl::Connect(m_handle, remoteAddress, &m_lastError); - + SocketState state = SocketImpl::Connect(m_handle, remoteAddress, &m_lastError); if (state != SocketState_NotConnected) m_peerAddress = remoteAddress; @@ -48,6 +43,8 @@ namespace Nz void TcpClient::EnableLowDelay(bool lowDelay) { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); + if (m_isLowDelayEnabled != lowDelay) { SocketImpl::SetBlocking(m_handle, lowDelay, &m_lastError); @@ -57,6 +54,8 @@ namespace Nz void TcpClient::EnableKeepAlive(bool keepAlive, UInt64 msTime, UInt64 msInterval) { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); + if (m_isKeepAliveEnabled != keepAlive || m_keepAliveTime != msTime || m_keepAliveInterval != msInterval) { SocketImpl::SetKeepAlive(m_handle, keepAlive, msTime, msInterval, &m_lastError); @@ -83,7 +82,7 @@ namespace Nz if (error == SocketError_NoError) { // No error yet, we're still connecting or connected, check that by connecting again - return Connect(m_peerAddress, 0); + return Connect(m_peerAddress); } else { @@ -118,6 +117,7 @@ namespace Nz bool TcpClient::Receive(void* buffer, std::size_t size, std::size_t* received) { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); NazaraAssert(buffer && size > 0, "Invalid buffer"); int read; @@ -146,6 +146,7 @@ namespace Nz bool TcpClient::Send(const void* buffer, std::size_t size, std::size_t* sent) { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); NazaraAssert(buffer && size > 0, "Invalid buffer"); CallOnExit updateSent; @@ -185,6 +186,46 @@ namespace Nz return true; } + bool TcpClient::WaitForConnected(UInt64 msTimeout) + { + switch (m_state) + { + case SocketState_Connected: + return true; + + case SocketState_Connecting: + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); + + CallOnExit restoreBlocking; + if (m_isBlockingEnabled) + { + SocketImpl::SetBlocking(m_handle, false); + restoreBlocking.Reset([this] () + { + SocketImpl::SetBlocking(m_handle, true); + }); + } + + 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 + if (newState == SocketState_NotConnected) + m_peerAddress = IpAddress::Invalid; + + UpdateState(newState); + return m_state == SocketState_Connected; + } + + case SocketState_NotConnected: + return false; + } + + NazaraInternalError("Unhandled socket state (0x" + String::Number(m_state, 16) + ')'); + return false; + } + void TcpClient::OnClose() { AbstractSocket::OnClose();