diff --git a/include/Nazara/Network/Enums.hpp b/include/Nazara/Network/Enums.hpp index 87eab41ae..5481d22a9 100644 --- a/include/Nazara/Network/Enums.hpp +++ b/include/Nazara/Network/Enums.hpp @@ -46,6 +46,7 @@ namespace Nz SocketError_NetworkError, //< The network system has failed (maybe network is down) SocketError_NotInitialized, //< Nazara network has not been initialized SocketError_NotSupported, //< The operation is not supported (e.g. creating a bluetooth socket on a system without any bluetooth adaptater) + SocketError_ResolveError, //< The hostname couldn't be resolved (more information in ResolveError code) SocketError_ResourceError, //< The operating system lacks the resources to proceed (e.g. memory/socket descriptor) SocketError_UnreachableHost, //< The host is not reachable SocketError_TimedOut, //< The operation timed out @@ -60,6 +61,7 @@ namespace Nz SocketState_Connecting, //< The socket is currently connecting SocketState_Connected, //< The socket is currently connected SocketState_NotConnected, //< The socket is not connected (or has been disconnected) + SocketState_Resolving, //< The socket is currently resolving a hostname SocketState_Max = SocketState_NotConnected }; diff --git a/include/Nazara/Network/IpAddress.hpp b/include/Nazara/Network/IpAddress.hpp index 5ac902a66..c9fa5c5b9 100644 --- a/include/Nazara/Network/IpAddress.hpp +++ b/include/Nazara/Network/IpAddress.hpp @@ -29,8 +29,8 @@ namespace Nz inline IpAddress(const IPv6& ip, UInt16 port = 0); inline IpAddress(const UInt8& a, const UInt8& b, const UInt8& c, const UInt8& d, UInt16 port = 0); inline 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 = 0); - inline IpAddress(const char* address); - inline IpAddress(const String& address); + inline explicit IpAddress(const char* address); + inline explicit IpAddress(const String& address); IpAddress(const IpAddress&) = default; IpAddress(IpAddress&&) = default; ~IpAddress() = default; diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index cd7f1dc16..7dbe2f1a6 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -24,6 +24,7 @@ namespace Nz ~TcpClient() = default; SocketState Connect(const IpAddress& remoteAddress); + SocketState Connect(const String& hostName, NetProtocol protocol = NetProtocol_Any, const String& service = "http", ResolveError* error = nullptr); inline void Disconnect(); void EnableLowDelay(bool lowDelay); diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 14d06ac97..ab825bb89 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -41,6 +41,34 @@ namespace Nz return state; } + SocketState TcpClient::Connect(const String& hostName, NetProtocol protocol, const String& service, ResolveError* error) + { + Disconnect(); + + UpdateState(SocketState_Resolving); + std::vector results = IpAddress::ResolveHostname(protocol, hostName, service, error); + if (results.empty()) + { + m_lastError = SocketError_ResolveError; + + UpdateState(SocketState_NotConnected); + return m_state; + } + + IpAddress hostnameAddress; + for (const HostnameInfo& result : results) + { + //TODO: Check PF_ type (TCP) + if (!result.address) + continue; + + hostnameAddress = result.address; + break; //< Take first valid address + } + + return Connect(hostnameAddress); + } + void TcpClient::EnableLowDelay(bool lowDelay) { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle");