diff --git a/Source/Engine/Platform/Base/NetworkBase.cpp b/Source/Engine/Platform/Base/NetworkBase.cpp index 7767d68eb..55218b657 100644 --- a/Source/Engine/Platform/Base/NetworkBase.cpp +++ b/Source/Engine/Platform/Base/NetworkBase.cpp @@ -12,22 +12,12 @@ bool NetworkBase::DestroySocket(NetworkSocket& socket) return true; } -bool NetworkBase::SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool value) -{ - return true; -} - bool NetworkBase::SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32 value) { return true; } -bool NetworkBase::GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool* value) -{ - return true; -} - -bool NetworkBase::GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32* value) +bool NetworkBase::GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32& value) { return true; } @@ -94,7 +84,6 @@ bool NetworkBase::GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, Ne void NetworkBase::RemoveSocketFromGroup(NetworkSocketGroup& group, uint32 index) { - } bool NetworkBase::RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket& socket) @@ -104,7 +93,6 @@ bool NetworkBase::RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket void NetworkBase::ClearGroup(NetworkSocketGroup& group) { - group.Count = 0; } int32 NetworkBase::WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint) @@ -117,7 +105,7 @@ int32 NetworkBase::ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferS return -1; } -bool NetworkBase::CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable) +bool NetworkBase::CreateEndPoint(const String& address, const String& port, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable) { return true; } diff --git a/Source/Engine/Platform/Base/NetworkBase.h b/Source/Engine/Platform/Base/NetworkBase.h index 1e65fbe7f..8615f31ac 100644 --- a/Source/Engine/Platform/Base/NetworkBase.h +++ b/Source/Engine/Platform/Base/NetworkBase.h @@ -4,50 +4,65 @@ #include "Engine/Core/Types/BaseTypes.h" #include "Engine/Core/Types/String.h" + API_INJECT_CPP_CODE("#include \"Engine/Platform/Network.h\""); -#define SOCKGROUP_ITEMSIZE 16 - -enum class FLAXENGINE_API NetworkProtocol +/// +/// Network connection protocol type. +/// +API_ENUM() enum class NetworkProtocol { /// Not specified. Undefined, /// User Datagram Protocol. Udp, /// Transmission Control Protocol. - Tcp + Tcp, }; -enum class FLAXENGINE_API NetworkIPVersion +/// +/// IP version type. +/// +API_ENUM() enum class NetworkIPVersion { /// Not specified. Undefined, /// Internet Protocol version 4. IPv4, /// Internet Protocol version 6. - IPv6 + IPv6, }; -struct FLAXENGINE_API NetworkSocket +/// +/// Network socket. +/// +API_STRUCT() struct FLAXENGINE_API NetworkSocket { - NetworkProtocol Protocol = NetworkProtocol::Undefined; - NetworkIPVersion IPVersion = NetworkIPVersion::Undefined; - byte Data[8] = {}; +DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkSocketGroup) + + /// Socket protocol type. + API_FIELD() NetworkProtocol Protocol = NetworkProtocol::Undefined; + /// Socket address IP version. + API_FIELD() NetworkIPVersion IPVersion = NetworkIPVersion::Undefined; + API_FIELD(Private, NoArray) byte Data[8] = {}; }; -struct FLAXENGINE_API NetworkAddress +/// +/// Network end-point. +/// +API_STRUCT() struct FLAXENGINE_API NetworkEndPoint { - String Address; - String Port; +DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkSocketGroup) + + /// End-point IP version. + API_FIELD(ReadOnly) NetworkIPVersion IPVersion = NetworkIPVersion::Undefined; + API_FIELD(Private, NoArray) byte Data[28] = {}; }; -struct FLAXENGINE_API NetworkEndPoint -{ - NetworkIPVersion IPVersion = NetworkIPVersion::Undefined; - byte Data[28] = {}; -}; - -enum class FLAXENGINE_API NetworkSocketOption +/// +/// Network socket options. +/// +API_ENUM() enum class NetworkSocketOption { /// Enables debugging info recording. Debug, @@ -81,29 +96,53 @@ enum class FLAXENGINE_API NetworkSocketOption IPv6Only, /// Retrieve the current path MTU, the socket must be connected UDP/TCP. Mtu, - // Socket type, DGRAM, STREAM .. - Type + /// Socket type, DGRAM, STREAM .. + Type, }; -struct FLAXENGINE_API NetworkSocketState +/// +/// Network socket state. +/// +API_ENUM() enum class NetworkSocketState { - bool Error = false; - bool Invalid = false; - bool Disconnected = false; - bool Readable = false; - bool Writeable = false; + /// Nothing. + None = 0, + /// Socket error. + Error = 1 << 0, + /// Invalid request. + Invalid = 1 << 1, + /// Socket disconnected. + Disconnected = 1 << 2, + /// Socket is readable. + Readable = 1 << 3, + /// Socket is writable. + Writeable = 1 << 4, }; -struct FLAXENGINE_API NetworkSocketGroup +DECLARE_ENUM_OPERATORS(NetworkSocketState); + +/// +/// Network sockets group. +/// +API_STRUCT() struct FLAXENGINE_API NetworkSocketGroup { - uint32 Count = 0; - uint32 Capacity = 0; - byte *Data; +DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkSocketGroup) + + /// Group size. + API_FIELD(ReadOnly) uint32 Count = 0; + /// Group capacity. + API_FIELD(ReadOnly) uint32 Capacity = 0; + API_FIELD(Private) byte* Data = nullptr; }; -class FLAXENGINE_API NetworkBase +/// +/// Low-level networking implementation interface with Berkeley sockets. +/// +API_CLASS(Static, Name="Network") class FLAXENGINE_API NetworkBase { public: + static struct FLAXENGINE_API ScriptingTypeInitializer TypeInitializer; + /// /// Creates a new native socket. /// @@ -111,14 +150,14 @@ public: /// The protocol. /// The ip version. /// Returns true on error, otherwise false. - static bool CreateSocket(NetworkSocket& socket, NetworkProtocol proto, NetworkIPVersion ipv); + API_FUNCTION() static bool CreateSocket(API_PARAM(Ref) NetworkSocket& socket, NetworkProtocol proto, NetworkIPVersion ipv); /// /// Closes native socket. /// /// The socket. /// Returns true on error, otherwise false. - static bool DestroySocket(NetworkSocket& socket); + API_FUNCTION() static bool DestroySocket(API_PARAM(Ref) NetworkSocket& socket); /// /// Sets the specified socket option. @@ -127,16 +166,7 @@ public: /// The option. /// The value. /// Returns true on error, otherwise false. - static bool SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool value); - - /// - /// Sets the specified socket option. - /// - /// The socket. - /// The option. - /// The value. - /// Returns true on error, otherwise false. - static bool SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32 value); + API_FUNCTION() static bool SetSocketOption(API_PARAM(Ref) NetworkSocket& socket, NetworkSocketOption option, int32 value); /// /// Gets the specified socket option. @@ -145,16 +175,7 @@ public: /// The option. /// The returned value. /// Returns true on error, otherwise false. - static bool GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool* value); - - /// - /// Gets the specified socket option. - /// - /// The socket. - /// The option. - /// The returned value. - /// Returns true on error, otherwise false. - static bool GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32* value); + API_FUNCTION() static bool GetSocketOption(API_PARAM(Ref) NetworkSocket& socket, NetworkSocketOption option, API_PARAM(Out) int32& value); /// /// Connects a socket to the specified end point. @@ -162,7 +183,7 @@ public: /// The socket. /// The end point. /// Returns true on error, otherwise false. - static bool ConnectSocket(NetworkSocket& socket, NetworkEndPoint& endPoint); + API_FUNCTION() static bool ConnectSocket(API_PARAM(Ref) NetworkSocket& socket, API_PARAM(Ref) NetworkEndPoint& endPoint); /// /// Binds a socket to the specified end point. @@ -170,7 +191,7 @@ public: /// The socket. /// The end point. /// Returns true on error, otherwise false. - static bool BindSocket(NetworkSocket& socket, NetworkEndPoint& endPoint); + API_FUNCTION() static bool BindSocket(API_PARAM(Ref) NetworkSocket& socket, API_PARAM(Ref) NetworkEndPoint& endPoint); /// /// Listens for incoming connection. @@ -178,7 +199,7 @@ public: /// The socket. /// Pending connection queue size. /// Returns true on error, otherwise false. - static bool Listen(NetworkSocket& socket, uint16 queueSize); + API_FUNCTION() static bool Listen(API_PARAM(Ref) NetworkSocket& socket, uint16 queueSize); /// /// Accepts a pending connection. @@ -187,21 +208,21 @@ public: /// The newly connected socket. /// The end point of the new socket. /// Returns true on error, otherwise false. - static bool Accept(NetworkSocket& serverSocket, NetworkSocket& newSocket, NetworkEndPoint& newEndPoint); + API_FUNCTION() static bool Accept(API_PARAM(Ref) NetworkSocket& serverSocket, API_PARAM(Ref) NetworkSocket& newSocket, API_PARAM(Out) NetworkEndPoint& newEndPoint); /// /// Checks for socket readability. /// /// The socket. /// Returns true when data is available. Otherwise false. - static bool IsReadable(NetworkSocket& socket); + API_FUNCTION() static bool IsReadable(API_PARAM(Ref) NetworkSocket& socket); /// /// Checks for socket writeability. /// /// The socket. /// Returns true when data can be written. Otherwise false. - static bool IsWritable(NetworkSocket& socket); + API_FUNCTION() static bool IsWritable(API_PARAM(Ref) NetworkSocket& socket); /// /// Creates a socket group. It allocate memory based on the desired capacity. @@ -209,21 +230,21 @@ public: /// The group capacity (fixed). /// The group. /// Returns true on error, otherwise false. - static bool CreateSocketGroup(uint32 capacity, NetworkSocketGroup& group); + API_FUNCTION() static bool CreateSocketGroup(uint32 capacity, API_PARAM(Out) NetworkSocketGroup& group); /// /// Destroy the socket group, and free the allocated memory. /// /// The group. /// Returns true if the group is already destroyed, otherwise false. - static bool DestroySocketGroup(NetworkSocketGroup& group); - + API_FUNCTION() static bool DestroySocketGroup(API_PARAM(Ref) NetworkSocketGroup& group); + /// /// Updates sockets states. /// /// The sockets group. /// Returns -1 on error, The number of elements where states are nonzero, otherwise 0. - static int32 Poll(NetworkSocketGroup& group); + API_FUNCTION() static int32 Poll(API_PARAM(Ref) NetworkSocketGroup& group); /// /// Retrieves socket state. @@ -232,7 +253,7 @@ public: /// The socket index in group. /// The returned state. /// Returns true on error, otherwise false. - static bool GetSocketState(NetworkSocketGroup& group, uint32 index, NetworkSocketState& state); + API_FUNCTION() static bool GetSocketState(API_PARAM(Ref) NetworkSocketGroup& group, uint32 index, API_PARAM(Out) NetworkSocketState& state); /// /// Adds a socket to a group. @@ -240,24 +261,23 @@ public: /// The group. /// The socket. /// Returns the socket index in group or -1 on error. - static int32 AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& socket); + API_FUNCTION() static int32 AddSocketToGroup(API_PARAM(Ref) NetworkSocketGroup& group, API_PARAM(Ref) NetworkSocket& socket); /// - /// Gets a socket by index. - /// Some data like socket IPVersion might be undefined. + /// Gets a socket by index. Some data like socket IPVersion might be undefined. /// /// The group. /// The index. /// The returned socket. /// Returns true on error, otherwise false. - static bool GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, NetworkSocket* socket); + API_FUNCTION() static bool GetSocketFromGroup(API_PARAM(Ref) NetworkSocketGroup& group, uint32 index, API_PARAM(Out) NetworkSocket* socket); /// /// Removes the socket at the specified index. /// /// The group. /// The index. - static void RemoveSocketFromGroup(NetworkSocketGroup& group, uint32 index); + API_FUNCTION() static void RemoveSocketFromGroup(API_PARAM(Ref) NetworkSocketGroup& group, uint32 index); /// /// Removes the socket if present. @@ -265,13 +285,13 @@ public: /// The group. /// The socket. /// Returns true if the socket is not found, otherwise false. - static bool RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket& socket); - + API_FUNCTION() static bool RemoveSocketFromGroup(API_PARAM(Ref) NetworkSocketGroup& group, API_PARAM(Ref) NetworkSocket& socket); + /// /// Clears the socket group. /// /// The group. - static void ClearGroup(NetworkSocketGroup& group); + API_FUNCTION() static void ClearGroup(API_PARAM(Ref) NetworkSocketGroup& group); /// /// Writes data to the socket. @@ -279,9 +299,9 @@ public: /// The socket. /// The data to write. /// The length of data. - /// If protocol is UDP , the destination end point. Otherwise nullptr. + /// If protocol is UDP, the destination end point. Otherwise nullptr. /// Returns -1 on error, otherwise bytes written. - static int32 WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint = nullptr); + API_FUNCTION() static int32 WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint = nullptr); /// /// Reads data on the socket. @@ -291,22 +311,23 @@ public: /// Size of the buffer. /// If UDP, the end point from where data is coming. Otherwise nullptr. /// Returns -1 on error, otherwise bytes read. - static int32 ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferSize, NetworkEndPoint* endPoint = nullptr); + API_FUNCTION() static int32 ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferSize, NetworkEndPoint* endPoint = nullptr); /// /// Creates an end point. /// - /// The address. + /// The network address. + /// The network port. /// The ip version. /// The created end point. /// True if the end point will be connected or binded. /// Returns true on error, otherwise false. - static bool CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = true); + API_FUNCTION() static bool CreateEndPoint(const String& address, const String& port, NetworkIPVersion ipv, API_PARAM(Out) NetworkEndPoint& endPoint, bool bindable = true); /// /// Remaps an ipv4 end point to an ipv6 one. /// /// The ipv4 end point. /// The ipv6 end point. - static NetworkEndPoint RemapEndPointToIPv6(NetworkEndPoint& endPoint); + API_FUNCTION() static NetworkEndPoint RemapEndPointToIPv6(API_PARAM(Ref) NetworkEndPoint& endPoint); }; diff --git a/Source/Engine/Platform/Base/PlatformBase.cs b/Source/Engine/Platform/Base/PlatformBase.cs deleted file mode 100644 index ee0ca5724..000000000 --- a/Source/Engine/Platform/Base/PlatformBase.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. - -namespace FlaxEngine -{ - partial class Platform - { - /// - /// Checks if current execution in on the main thread. - /// - /// True if running on the main thread, otherwise false. - public static bool IsInMainThread => CurrentThreadID == Globals.MainThreadID; - } -} diff --git a/Source/Engine/Platform/Platform.cs b/Source/Engine/Platform/Platform.cs new file mode 100644 index 000000000..118e326fc --- /dev/null +++ b/Source/Engine/Platform/Platform.cs @@ -0,0 +1,79 @@ +// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. + +using System; + +namespace FlaxEngine +{ + partial class Platform + { + /// + /// Checks if current execution in on the main thread. + /// + public static bool IsInMainThread => CurrentThreadID == Globals.MainThreadID; + } + + partial class Network + { + /// + /// Writes data to the socket. + /// + /// The socket. + /// The data to write. + /// Returns -1 on error, otherwise bytes written. + [Unmanaged] + public static unsafe int WriteSocket(NetworkSocket socket, byte[] data) + { + if (data == null) + throw new ArgumentNullException(nameof(data)); + fixed (byte* ptr = data) + return Internal_WriteSocket(ref socket, ptr, (uint)data.Length, null); + } + + /// + /// Writes data to the socket. + /// + /// The socket. + /// The data to write. + /// If protocol is UDP, the destination end point. + /// Returns -1 on error, otherwise bytes written. + [Unmanaged] + public static unsafe int WriteSocket(NetworkSocket socket, byte[] data, NetworkEndPoint endPoint) + { + if (data == null) + throw new ArgumentNullException(nameof(data)); + fixed (byte* ptr = data) + return Internal_WriteSocket(ref socket, ptr, (uint)data.Length, &endPoint); + } + + /// + /// Reads data on the socket. + /// + /// The socket. + /// The buffer. + /// Returns -1 on error, otherwise bytes read. + [Unmanaged] + public static unsafe int ReadSocket(NetworkSocket socket, byte[] buffer) + { + if (buffer == null) + throw new ArgumentNullException(nameof(buffer)); + fixed (byte* ptr = buffer) + return Internal_ReadSocket(ref socket, ptr, (uint)buffer.Length, null); + } + + /// + /// Reads data on the socket. + /// + /// The socket. + /// The buffer. + /// If UDP, the end point from where data is coming. Otherwise nullptr. + /// Returns -1 on error, otherwise bytes read. + [Unmanaged] + public static unsafe int ReadSocket(NetworkSocket socket, byte[] buffer, NetworkEndPoint endPoint) + { + if (buffer == null) + throw new ArgumentNullException(nameof(buffer)); + fixed (byte* ptr = buffer) + return Internal_ReadSocket(ref socket, ptr, (uint)buffer.Length, &endPoint); + } + } +} diff --git a/Source/Engine/Platform/Unix/UnixNetwork.cpp b/Source/Engine/Platform/Unix/UnixNetwork.cpp index 139695119..d37b07952 100644 --- a/Source/Engine/Platform/Unix/UnixNetwork.cpp +++ b/Source/Engine/Platform/Unix/UnixNetwork.cpp @@ -4,7 +4,6 @@ #include "UnixNetwork.h" #include "Engine/Core/Log.h" -#include "Engine/Core/Collections/Array.h" #include "Engine/Utilities/StringConverter.h" #include #include @@ -19,6 +18,7 @@ struct UnixSocketData { int sockfd; }; + static_assert(sizeof(NetworkSocket::Data) >= sizeof(UnixSocketData), "NetworkSocket::Data is not big enough to contains UnixSocketData !"); static_assert(sizeof(NetworkEndPoint::Data) >= sizeof(sockaddr_in6), "NetworkEndPoint::Data is not big enough to contains sockaddr_in6 !"); @@ -32,11 +32,6 @@ static int GetAddrSizeFromEP(NetworkEndPoint& endPoint) return endPoint.IPVersion == NetworkIPVersion::IPv6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in); } -static NetworkIPVersion GetIPVersionFromAddr(const sockaddr& addr) -{ - return addr.sa_family == AF_INET6 ? NetworkIPVersion::IPv6 : NetworkIPVersion::IPv4;; -} - static void TranslateSockOptToNative(NetworkSocketOption option, int32* level, int32* name) { switch (option) @@ -100,7 +95,7 @@ static bool CreateEndPointFromAddr(sockaddr* addr, NetworkEndPoint& endPoint) } char strPort[6]; sprintf(strPort, "%d", port); - endPoint.IPVersion = GetIPVersionFromAddr(*addr); + endPoint.IPVersion = addr->sa_family == AF_INET6 ? NetworkIPVersion::IPv6 : NetworkIPVersion::IPv4; memcpy(endPoint.Data, addr, size); return false; } @@ -130,12 +125,6 @@ bool UnixNetwork::DestroySocket(NetworkSocket& socket) return false; } -bool UnixNetwork::SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool value) -{ - const int32 v = value; - return SetSocketOption(socket, option, v); -} - bool UnixNetwork::SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32 value) { int32 optlvl = 0; @@ -151,22 +140,14 @@ bool UnixNetwork::SetSocketOption(NetworkSocket& socket, NetworkSocketOption opt return false; } -bool UnixNetwork::GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool* value) -{ - int32 v; - const bool status = GetSocketOption(socket, option, &v); - *value = v == 1 ? true : false; - return status; -} - -bool UnixNetwork::GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32* value) +bool UnixNetwork::GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32& value) { int32 optlvl = 0; int32 optnme = 0; TranslateSockOptToNative(option, &optlvl, &optnme); socklen_t size; auto& sock = *(UnixSocketData*)&socket.Data; - if (getsockopt(sock.sockfd, optlvl, optnme, (char*)value, &size) == -1) + if (getsockopt(sock.sockfd, optlvl, optnme, (char*)&value, &size) == -1) { LOG(Warning, "Unable to get socket option ! Socket : {0}", sock.sockfd); LOG_UNIX_LAST_ERROR; @@ -177,7 +158,7 @@ bool UnixNetwork::GetSocketOption(NetworkSocket& socket, NetworkSocketOption opt bool UnixNetwork::ConnectSocket(NetworkSocket& socket, NetworkEndPoint& endPoint) { - const uint16 size = GetAddrSizeFromEP(endPoint); + const int size = GetAddrSizeFromEP(endPoint); auto& sock = *(UnixSocketData*)&socket.Data; if (connect(sock.sockfd, (const sockaddr*)endPoint.Data, size) == -1) { @@ -196,7 +177,7 @@ bool UnixNetwork::BindSocket(NetworkSocket& socket, NetworkEndPoint& endPoint) LOG(Error, "Can't bind socket to end point, Socket.IPVersion != EndPoint.IPVersion! Socket : {0}", sock.sockfd); return true; } - const uint16 size = GetAddrSizeFromEP(endPoint); + const int size = GetAddrSizeFromEP(endPoint); if (bind(sock.sockfd, (const sockaddr*)endPoint.Data, size) == -1) { LOG(Error, "Unable to bind socket! Socket : {0}", sock.sockfd); @@ -244,61 +225,6 @@ bool UnixNetwork::Accept(NetworkSocket& serverSocket, NetworkSocket& newSocket, return false; } -bool UnixNetwork::IsReadable(NetworkSocket& socket) -{ - return NetworkBase::IsReadable(socket); // TODO: impl this -} - -bool UnixNetwork::IsWritable(NetworkSocket& socket) -{ - return NetworkBase::IsWritable(socket); // TODO: impl this -} - -bool UnixNetwork::CreateSocketGroup(uint32 capacity, NetworkSocketGroup& group) -{ - return NetworkBase::CreateSocketGroup(capacity, group); // TODO: impl this -} - -bool UnixNetwork::DestroySocketGroup(NetworkSocketGroup& group) -{ - return NetworkBase::DestroySocketGroup(group); // TODO: impl this -} - -int32 UnixNetwork::Poll(NetworkSocketGroup& group) -{ - return NetworkBase::Poll(group); // TODO: impl this -} - -bool UnixNetwork::GetSocketState(NetworkSocketGroup& group, uint32 index, NetworkSocketState& state) -{ - return NetworkBase::GetSocketState(group, index, state); // TODO: impl this -} - -int32 UnixNetwork::AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& socket) -{ - return NetworkBase::AddSocketToGroup(group, socket); // TODO: impl this -} - -bool UnixNetwork::GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, NetworkSocket* socket) -{ - return NetworkBase::GetSocketFromGroup(group, index, socket); // TODO: impl this -} - -void UnixNetwork::RemoveSocketFromGroup(NetworkSocketGroup& group, uint32 index) -{ - NetworkBase::RemoveSocketFromGroup(group, index); // TODO: impl this -} - -bool UnixNetwork::RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket& socket) -{ - return NetworkBase::RemoveSocketFromGroup(group, socket); // TODO: impl this -} - -void UnixNetwork::ClearGroup(NetworkSocketGroup& group) -{ - NetworkBase::ClearGroup(group); // TODO: impl this -} - int32 UnixNetwork::WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint) { auto& sock = *(UnixSocketData*)&socket.Data; @@ -361,7 +287,7 @@ int32 UnixNetwork::ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferS return size; } -bool UnixNetwork::CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable) +bool UnixNetwork::CreateEndPoint(const String& address, const String& port, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable) { int status; addrinfo hints; @@ -372,22 +298,18 @@ bool UnixNetwork::CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, hints.ai_flags |= AI_V4MAPPED; if (bindable) hints.ai_flags = AI_PASSIVE; - - // consider using NUMERICHOST/NUMERICSERV if address is a valid Ipv4 or IPv6 so we can skip some look up ( potentially slow when resolving host names ) - const StringAsANSI<60> addressAnsi(*address.Address, address.Address.Length()); - const StringAsANSI<10> portAnsi(*address.Port, address.Port.Length()); - if ((status = getaddrinfo(address.Address == String::Empty ? nullptr : addressAnsi.Get(), address.Port == String::Empty ? nullptr : portAnsi.Get(), &hints, &info)) != 0) + const StringAsANSI<60> addressAnsi(*address, address.Length()); + const StringAsANSI<10> portAnsi(*port, port.Length()); + if ((status = getaddrinfo(address.IsEmpty() ? nullptr : addressAnsi.Get(), port.IsEmpty() ? nullptr : portAnsi.Get(), &hints, &info)) != 0) { - LOG(Error, "Unable to query info for address : {0} Error : {1}", address.Address != String::Empty ? *address.Address : TEXT("ANY"), String(gai_strerror(status))); + LOG(Error, "Unable to query info for address : {0}::{1} Error : {2}", address, port, String(gai_strerror(status))); return true; } - if (info == nullptr) { - LOG(Error, "Unable to resolve address! Address : {0}", address.Address != String::Empty ? *address.Address : TEXT("ANY")); + LOG(Error, "Unable to resolve address! Address : {0}::{1}", address, port); return true; } - if (CreateEndPointFromAddr(info->ai_addr, endPoint)) { freeaddrinfo(info); @@ -397,9 +319,4 @@ bool UnixNetwork::CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, return false; } -NetworkEndPoint UnixNetwork::RemapEndPointToIPv6(NetworkEndPoint endPoint) -{ - return NetworkBase::RemapEndPointToIPv6(endPoint); // TODO: impl this -} - #endif diff --git a/Source/Engine/Platform/Unix/UnixNetwork.h b/Source/Engine/Platform/Unix/UnixNetwork.h index 58c27c453..4557303a5 100644 --- a/Source/Engine/Platform/Unix/UnixNetwork.h +++ b/Source/Engine/Platform/Unix/UnixNetwork.h @@ -13,28 +13,15 @@ public: // [NetworkBase] static bool CreateSocket(NetworkSocket& socket, NetworkProtocol proto, NetworkIPVersion ipv); static bool DestroySocket(NetworkSocket& socket); - static bool SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool value); static bool SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32 value); - static bool GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool* value); - static bool GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32* value); + static bool GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32& value); static bool ConnectSocket(NetworkSocket& socket, NetworkEndPoint& endPoint); static bool BindSocket(NetworkSocket& socket, NetworkEndPoint& endPoint); static bool Listen(NetworkSocket& socket, uint16 queueSize); static bool Accept(NetworkSocket& serverSocket, NetworkSocket& newSocket, NetworkEndPoint& newEndPoint); - static bool IsReadable(NetworkSocket& socket); - static bool IsWritable(NetworkSocket& socket); - static bool CreateSocketGroup(uint32 capacity, NetworkSocketGroup& group); - static bool DestroySocketGroup(NetworkSocketGroup& group); - static int32 Poll(NetworkSocketGroup& group); - static bool GetSocketState(NetworkSocketGroup& group, uint32 index, NetworkSocketState& state); - static int32 AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& socket); - static bool GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, NetworkSocket* socket); - static void RemoveSocketFromGroup(NetworkSocketGroup& group, uint32 index); - static bool RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket& socket); - static void ClearGroup(NetworkSocketGroup& group); static int32 WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint = nullptr); static int32 ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferSize, NetworkEndPoint* endPoint = nullptr); - static bool CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = true); + static bool CreateEndPoint(const String& address, const String& port, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = true); static NetworkEndPoint RemapEndPointToIPv6(NetworkEndPoint endPoint); }; diff --git a/Source/Engine/Platform/Win32/Win32Network.cpp b/Source/Engine/Platform/Win32/Win32Network.cpp index a5edd68e3..2e77d93cb 100644 --- a/Source/Engine/Platform/Win32/Win32Network.cpp +++ b/Source/Engine/Platform/Win32/Win32Network.cpp @@ -4,34 +4,24 @@ #include "Win32Network.h" #include "Engine/Core/Log.h" -#include "Engine/Core/Collections/Array.h" #include #include #include +#define SOCKGROUP_ITEMSIZE 16 + static_assert(sizeof(NetworkSocket::Data) >= sizeof(SOCKET), "NetworkSocket::Data is not big enough to contains SOCKET !"); static_assert(sizeof(NetworkEndPoint::Data) >= sizeof(sockaddr_in6), "NetworkEndPoint::Data is not big enough to contains sockaddr_in6 !"); static_assert(SOCKGROUP_ITEMSIZE >= sizeof(pollfd), "SOCKGROUP_ITEMSIZE macro is not big enough to contains pollfd !"); // @formatter:off -static const IN6_ADDR v4MappedPrefix = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }; +static const IN6_ADDR v4MappedPrefix = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }; // @formatter:on -/* - * Todo : - * Return precise errors so user can understand what's happening ( disconnected, ect ... ) - * Known issues : - * Even if dualstacking is enabled it's not possible to bind an Ipv4mappedIPv6 endpoint. windows limitation - */ - static String GetErrorMessage(int error) { wchar_t* s = nullptr; - FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, error, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - reinterpret_cast(&s), 0, nullptr); + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast(&s), 0, nullptr); String str(s); LocalFree(s); return str; @@ -52,11 +42,6 @@ static int GetAddrSizeFromEP(NetworkEndPoint& endPoint) return endPoint.IPVersion == NetworkIPVersion::IPv6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in); } -static NetworkIPVersion GetIPVersionFromAddr(const sockaddr& addr) -{ - return addr.sa_family == AF_INET6 ? NetworkIPVersion::IPv6 : NetworkIPVersion::IPv4;; -} - static bool CreateEndPointFromAddr(sockaddr* addr, NetworkEndPoint& endPoint) { uint32 size = GetAddrSize(*addr); @@ -86,34 +71,11 @@ static bool CreateEndPointFromAddr(sockaddr* addr, NetworkEndPoint& endPoint) } char strPort[6]; _itoa(port, strPort, 10); - endPoint.IPVersion = GetIPVersionFromAddr(*addr); + endPoint.IPVersion = addr->sa_family == AF_INET6 ? NetworkIPVersion::IPv6 : NetworkIPVersion::IPv4; memcpy(endPoint.Data, addr, size); return false; } -static void PrintAddrFromInfo(addrinfoW& info) -{ - addrinfoW* curr; - for (curr = &info; curr != nullptr; curr = curr->ai_next) - { - void* addr; - if (curr->ai_family == AF_INET) - { - sockaddr_in* ipv4 = (struct sockaddr_in*)curr->ai_addr; - addr = &(ipv4->sin_addr); - } - else - { - sockaddr_in6* ipv6 = (struct sockaddr_in6*)curr->ai_addr; - addr = &(ipv6->sin6_addr); - } - - char str[INET6_ADDRSTRLEN]; - inet_ntop(curr->ai_family, addr, str, INET6_ADDRSTRLEN); - LOG(Info, "ADDR INFO family : {0} socktype : {1}, proto : {2} address : {3}", curr->ai_family, curr->ai_socktype, curr->ai_protocol, StringAnsi(str).ToString()); - } -} - static void TranslateSockOptToNative(NetworkSocketOption option, int32* level, int32* name) { switch (option) @@ -152,7 +114,6 @@ bool Win32Network::CreateSocket(NetworkSocket& socket, NetworkProtocol proto, Ne const uint8 stype = socket.Protocol == NetworkProtocol::Tcp ? SOCK_STREAM : SOCK_DGRAM; const uint8 prot = socket.Protocol == NetworkProtocol::Tcp ? IPPROTO_TCP : IPPROTO_UDP; SOCKET sock; - if ((sock = ::socket(family, stype, prot)) == INVALID_SOCKET) { LOG(Error, "Can't create native socket! Error : {0}", GetLastErrorMessage()); @@ -163,7 +124,7 @@ bool Win32Network::CreateSocket(NetworkSocket& socket, NetworkProtocol proto, Ne if (ioctlsocket(sock, FIONBIO, &value) == SOCKET_ERROR) { LOG(Error, "Can't set socket to NON-BLOCKING type! Error : {0}", GetLastErrorMessage()); - return true; // Support using blocking socket , need to test it + return true; } return false; } @@ -180,19 +141,11 @@ bool Win32Network::DestroySocket(NetworkSocket& socket) return true; } -bool Win32Network::SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool value) -{ - const int32 v = value; - return SetSocketOption(socket, option, v); -} - bool Win32Network::SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32 value) { int32 optlvl = 0; int32 optnme = 0; - TranslateSockOptToNative(option, &optlvl, &optnme); - if (setsockopt(*(SOCKET*)socket.Data, optlvl, optnme, (char*)&value, sizeof(value)) == SOCKET_ERROR) { LOG(Warning, "Unable to set socket option ! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage()); @@ -201,23 +154,13 @@ bool Win32Network::SetSocketOption(NetworkSocket& socket, NetworkSocketOption op return false; } -bool Win32Network::GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool* value) -{ - int32 v; - const bool status = GetSocketOption(socket, option, &v); - *value = v == 1 ? true : false; - return status; -} - -bool Win32Network::GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32* value) +bool Win32Network::GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32& value) { int32 optlvl = 0; int32 optnme = 0; - TranslateSockOptToNative(option, &optlvl, &optnme); - int32 size; - if (getsockopt(*(SOCKET*)socket.Data, optlvl, optnme, (char*)value, &size) == SOCKET_ERROR) + if (getsockopt(*(SOCKET*)socket.Data, optlvl, optnme, (char*)&value, &size) == SOCKET_ERROR) { LOG(Warning, "Unable to get socket option ! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage()); return true; @@ -227,10 +170,10 @@ bool Win32Network::GetSocketOption(NetworkSocket& socket, NetworkSocketOption op bool Win32Network::ConnectSocket(NetworkSocket& socket, NetworkEndPoint& endPoint) { - const uint16 size = GetAddrSizeFromEP(endPoint); + const int size = GetAddrSizeFromEP(endPoint); if (connect(*(SOCKET*)socket.Data, (const sockaddr*)endPoint.Data, size) == SOCKET_ERROR) { - int error = WSAGetLastError(); + const int error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) return false; LOG(Error, "Unable to connect socket to address! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetErrorMessage(error)); @@ -246,8 +189,7 @@ bool Win32Network::BindSocket(NetworkSocket& socket, NetworkEndPoint& endPoint) LOG(Error, "Can't bind socket to end point, Socket.IPVersion != EndPoint.IPVersion! Socket : {0}", *(SOCKET*)socket.Data); return true; } - - const uint16 size = GetAddrSizeFromEP(endPoint); + const int size = GetAddrSizeFromEP(endPoint); if (bind(*(SOCKET*)socket.Data, (const sockaddr*)endPoint.Data, size) == SOCKET_ERROR) { LOG(Error, "Unable to bind socket! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetLastErrorMessage()); @@ -278,7 +220,7 @@ bool Win32Network::Accept(NetworkSocket& serverSocket, NetworkSocket& newSocket, int32 size = sizeof(sockaddr_in6); if ((sock = accept(*(SOCKET*)serverSocket.Data, (sockaddr*)&addr, &size)) == INVALID_SOCKET) { - int32 error = WSAGetLastError(); + const int error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) return false; LOG(Warning, "Unable to accept incoming connection! Socket : {0} Error : {1}", *(SOCKET*)serverSocket.Data, GetErrorMessage(error)); @@ -300,7 +242,7 @@ bool Win32Network::IsReadable(NetworkSocket& socket) entry.events = POLLRDNORM; if (WSAPoll(&entry, 1, 0) == SOCKET_ERROR) { - int32 error = WSAGetLastError(); + const int error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) return false; LOG(Error, "Unable to poll socket! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetErrorMessage(error)); @@ -318,7 +260,7 @@ bool Win32Network::IsWritable(NetworkSocket& socket) entry.events = POLLWRNORM; if (WSAPoll(&entry, 1, 0) == SOCKET_ERROR) { - int32 error = WSAGetLastError(); + const int error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) return false; LOG(Error, "Unable to poll socket! Socket : {0} Error : {1}", *(SOCKET*)socket.Data, GetErrorMessage(error)); @@ -331,15 +273,15 @@ bool Win32Network::IsWritable(NetworkSocket& socket) bool Win32Network::CreateSocketGroup(uint32 capacity, NetworkSocketGroup& group) { - if (!(group.Data = (byte*)Platform::Allocate(capacity * SOCKGROUP_ITEMSIZE, 16))) + group.Data = (byte*)Platform::Allocate(capacity * SOCKGROUP_ITEMSIZE, 16); + if (!group.Data) { LOG(Error, "Unable to malloc NetworkSocketGroup::Data ! Size : {0}", capacity * SOCKGROUP_ITEMSIZE); return true; } group.Capacity = capacity; - for (int i = 0; i < (int)group.Capacity; i++) + for (uint32 i = 0; i < group.Capacity; i++) ((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd = -1; - return false; } @@ -353,7 +295,7 @@ bool Win32Network::DestroySocketGroup(NetworkSocketGroup& group) int32 Win32Network::Poll(NetworkSocketGroup& group) { - int32 pollret = WSAPoll((pollfd*)group.Data, group.Count, 0); + const int pollret = WSAPoll((pollfd*)group.Data, group.Count, 0); if (pollret == SOCKET_ERROR) LOG(Error, "Unable to poll socket group! Error : {0}", GetLastErrorMessage()); return pollret; @@ -364,17 +306,17 @@ bool Win32Network::GetSocketState(NetworkSocketGroup& group, uint32 index, Netwo if (index >= group.Capacity) return true; pollfd* pollptr = (pollfd*)&group.Data[index * SOCKGROUP_ITEMSIZE]; - memset(&state, 0, sizeof(state)); + state = NetworkSocketState::None; if (pollptr->revents & POLLERR) - state.Error = true; + state |= NetworkSocketState::Error; if (pollptr->revents & POLLHUP) - state.Disconnected = true; + state |= NetworkSocketState::Disconnected; if (pollptr->revents & POLLNVAL) - state.Invalid = true; + state |= NetworkSocketState::Invalid; if (pollptr->revents & POLLRDNORM) - state.Readable = true; + state |= NetworkSocketState::Readable; if (pollptr->revents & POLLWRNORM) - state.Writeable = true; + state |= NetworkSocketState::Writeable; return false; } @@ -382,12 +324,10 @@ int32 Win32Network::AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& s { if (group.Count >= group.Capacity) return -1; - pollfd pollinfo; pollinfo.fd = *(SOCKET*)socket.Data; pollinfo.events = POLLRDNORM | POLLWRNORM; - - for (int i = 0; i < (int)group.Capacity; i++) + for (uint32 i = 0; i < group.Capacity; i++) { if (((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd == -1) { @@ -406,7 +346,7 @@ bool Win32Network::GetSocketFromGroup(NetworkSocketGroup& group, uint32 index, N SOCKET s = ((pollfd*)&group.Data[index * SOCKGROUP_ITEMSIZE])->fd; memcpy(socket->Data, &s, sizeof(s)); int32 value; - if (GetSocketOption(*socket, NetworkSocketOption::Type, &value)) + if (GetSocketOption(*socket, NetworkSocketOption::Type, value)) return true; if (value == SOCK_DGRAM) socket->Protocol = NetworkProtocol::Udp; @@ -442,7 +382,7 @@ bool Win32Network::RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocke void Win32Network::ClearGroup(NetworkSocketGroup& group) { - for (int i = 0; i < (int)group.Capacity; i++) + for (uint32 i = 0; i < group.Capacity; i++) ((pollfd*)&group.Data[i * SOCKGROUP_ITEMSIZE])->fd = -1; group.Count = 0; } @@ -487,7 +427,7 @@ int32 Win32Network::ReadSocket(NetworkSocket socket, byte* buffer, uint32 buffer { if ((size = recv(*(SOCKET*)socket.Data, (char*)buffer, bufferSize, 0)) == SOCKET_ERROR) { - const int32 error = WSAGetLastError(); + const int error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) return 0; LOG(Error, "Unable to read data! Socket : {0} Buffer Size : {1} Error : {2}", *(SOCKET*)socket.Data, bufferSize, GetErrorMessage(error)); @@ -509,9 +449,9 @@ int32 Win32Network::ReadSocket(NetworkSocket socket, byte* buffer, uint32 buffer return size; } -bool Win32Network::CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable) +bool Win32Network::CreateEndPoint(const String& address, const String& port, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable) { - int status; + INT status; addrinfoW hints; addrinfoW* info; memset(&hints, 0, sizeof(hints)); @@ -520,20 +460,17 @@ bool Win32Network::CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, hints.ai_flags |= AI_V4MAPPED; if (bindable) hints.ai_flags = AI_PASSIVE; - - // consider using NUMERICHOST/NUMERICSERV if address is a valid Ipv4 or IPv6 so we can skip some look up ( potentially slow when resolving host names ) - if ((status = GetAddrInfoW(address.Address == String::Empty ? nullptr : address.Address.Get(), address.Port == String::Empty ? nullptr : address.Port.Get(), &hints, &info)) != 0) + // Consider using NUMERICHOST/NUMERICSERV if address is a valid Ipv4 or IPv6 so we can skip some look up ( potentially slow when resolving host names ) + if ((status = GetAddrInfoW(address.IsEmpty() ? nullptr : *address, port.IsEmpty() ? nullptr : *port, &hints, &info)) != 0) { - LOG(Error, "Unable to query info for address : {0} Error : {1}", address.Address != String::Empty ? *address.Address : TEXT("ANY"), gai_strerror(status)); + LOG(Error, "Unable to query info for address : {0}::{1} Error : {2}", address, port, gai_strerror(status)); return true; } - if (info == nullptr) { - LOG(Error, "Unable to resolve address! Address : {0}", address.Address != String::Empty ? *address.Address : TEXT("ANY")); + LOG(Error, "Unable to resolve address! Address : {0}::{1}", address, port); return true; } - if (CreateEndPointFromAddr(info->ai_addr, endPoint)) { FreeAddrInfoW(info); @@ -543,7 +480,7 @@ bool Win32Network::CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, return false; } -NetworkEndPoint Win32Network::RemapEndPointToIPv6(NetworkEndPoint endPoint) +NetworkEndPoint Win32Network::RemapEndPointToIPv6(NetworkEndPoint& endPoint) { if (endPoint.IPVersion == NetworkIPVersion::IPv6) { diff --git a/Source/Engine/Platform/Win32/Win32Network.h b/Source/Engine/Platform/Win32/Win32Network.h index 4949b8a38..c8c281e2a 100644 --- a/Source/Engine/Platform/Win32/Win32Network.h +++ b/Source/Engine/Platform/Win32/Win32Network.h @@ -13,10 +13,8 @@ public: // [NetworkBase] static bool CreateSocket(NetworkSocket& socket, NetworkProtocol proto, NetworkIPVersion ipv); static bool DestroySocket(NetworkSocket& socket); - static bool SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool value); static bool SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32 value); - static bool GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool* value); - static bool GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32* value); + static bool GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32& value); static bool ConnectSocket(NetworkSocket& socket, NetworkEndPoint& endPoint); static bool BindSocket(NetworkSocket& socket, NetworkEndPoint& endPoint); static bool Listen(NetworkSocket& socket, uint16 queueSize); @@ -34,8 +32,8 @@ public: static void ClearGroup(NetworkSocketGroup& group); static int32 WriteSocket(NetworkSocket socket, byte* data, uint32 length, NetworkEndPoint* endPoint = nullptr); static int32 ReadSocket(NetworkSocket socket, byte* buffer, uint32 bufferSize, NetworkEndPoint* endPoint = nullptr); - static bool CreateEndPoint(NetworkAddress& address, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = true); - static NetworkEndPoint RemapEndPointToIPv6(NetworkEndPoint endPoint); + static bool CreateEndPoint(const String& address, const String& port, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = true); + static NetworkEndPoint RemapEndPointToIPv6(NetworkEndPoint& endPoint); }; #endif