// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Types/BaseTypes.h" #include "Engine/Core/Types/String.h" API_INJECT_CPP_CODE("#include \"Engine/Platform/Network.h\""); #define SOCKGROUP_MAXCOUNT 64 #define SOCKGROUP_ITEMSIZE 16 enum class FLAXENGINE_API NetworkProtocol { /// Not specified. Undefined, /// User Datagram Protocol. Udp, /// Transmission Control Protocol. Tcp }; enum class FLAXENGINE_API NetworkIPVersion { /// Not specified. Undefined, /// Internet Protocol version 4. IPv4, /// Internet Protocol version 6. IPv6 }; struct FLAXENGINE_API NetworkSocket { NetworkProtocol Protocol = NetworkProtocol::Undefined; NetworkIPVersion IPVersion = NetworkIPVersion::Undefined; byte Data[8] = {}; }; struct FLAXENGINE_API NetworkEndPoint { NetworkIPVersion IPVersion = NetworkIPVersion::Undefined; String Address; String Port; byte Data[28] = {}; }; enum class FLAXENGINE_API NetworkSocketOption { /// Enables debugging info recording. Debug, /// Allows local address reusing. ReuseAddr, /// Keeps connections alive. KeepAlive, /// Indicates that outgoing data should be sent on whatever interface the socket is bound to and not a routed on some other interface. DontRoute, /// Allows for sending broadcast data. Broadcast, /// Uses the local loopback address when sending data from this socket. UseLoopback, /// Lingers on close if data present. Linger, /// Allows out-of-bound data to be returned in-line with regular data. OOBInline, /// Socket send data buffer size. SendBuffer, /// Socket receive data buffer size. RecvBuffer, /// The timeout in milliseconds for blocking send calls. SendTimeout, /// The timeout in milliseconds for blocking receive calls. RecvTimeout, /// The last socket error code. Error, /// Enables the Nagle algorithm for TCP sockets. NoDelay, /// Enables IPv6/Ipv4 dual-stacking, UDP/TCP. IPv6Only, /// Retrieve the current path MTU, the socket must be connected UDP/TCP. Mtu }; struct FLAXENGINE_API NetworkSocketState { bool Error = false; bool Invalid = false; bool Disconnected = false; bool Readable = false; bool Writeable = false; }; struct FLAXENGINE_API NetworkSocketGroup { uint32 Count = 0; byte Data[SOCKGROUP_MAXCOUNT * SOCKGROUP_ITEMSIZE] = {}; }; class FLAXENGINE_API NetworkBase { public: /// /// Creates a new native socket. /// /// The socket struct to fill in. /// The protocol. /// The ip version. /// Returns true on error, otherwise false. static bool CreateSocket(NetworkSocket& socket, NetworkProtocol proto, NetworkIPVersion ipv); /// /// Closes native socket. /// /// The socket. /// Returns true on error, otherwise false. static bool DestroySocket(NetworkSocket& socket); /// /// Sets the specified socket option. /// /// The socket. /// 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); /// /// 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, 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); /// /// Connects a socket to the specified end point. /// /// The socket. /// The end point. /// Returns true on error, otherwise false. static bool ConnectSocket(NetworkSocket& socket, NetworkEndPoint& endPoint); /// /// Binds a socket to the specified end point. /// /// The socket. /// The end point. /// Returns true on error, otherwise false. static bool BindSocket(NetworkSocket& socket, NetworkEndPoint& endPoint); /// /// Listens for incoming connection. /// /// The socket. /// Pending connection queue size. /// Returns true on error, otherwise false. static bool Listen(NetworkSocket& socket, uint16 queueSize); /// /// Accepts a pending connection. /// /// The socket. /// The newly connected socket. /// The end point of the new socket. /// Returns true on error, otherwise false. static bool Accept(NetworkSocket& serverSock, NetworkSocket& newSock, NetworkEndPoint& newEndPoint); /// /// Checks for socket readability. /// /// The socket. /// Returns true when data is available. Otherwise false. static bool IsReadable(NetworkSocket& socket); /// /// Checks for socket writeability. /// /// The socket. /// Returns true when data can be written. Otherwise false. static bool IsWriteable(NetworkSocket& socket); /// /// 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); /// /// Retrieves socket state. /// /// The group. /// The socket index in group. /// The returned state. /// Returns true on error, otherwise false. static bool GetSocketState(NetworkSocketGroup& group, uint32 index, NetworkSocketState& state); /// /// Adds a socket to a group. /// /// The group. /// The socket. /// Returns the socket index in group or -1 on error. static int32 AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& socket); /// /// Clears the socket group. /// /// The group. static void ClearGroup(NetworkSocketGroup& group); /// /// Writes data to the socket. /// /// The socket. /// The data to write. /// The length of data. /// 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); /// /// Reads data on the socket. /// /// The socket. /// The buffer. /// 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); /// /// Creates an end point. /// /// The address (hostname, IPv4 or IPv6). /// The 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(String* address, String* port, NetworkIPVersion ipv, NetworkEndPoint& endPoint, bool bindable = false); /// /// Remaps an ipv4 end point to an ipv6 one. /// /// The ipv4 end point. /// The ipv6 end point. static NetworkEndPoint RemapEndPointToIPv6(NetworkEndPoint& endPoint); };