Refactor Network api, add more dcos, expose it to scripting
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// Network connection protocol type.
|
||||
/// </summary>
|
||||
API_ENUM() enum class NetworkProtocol
|
||||
{
|
||||
/// <summary>Not specified.</summary>
|
||||
Undefined,
|
||||
/// <summary>User Datagram Protocol.</summary>
|
||||
Udp,
|
||||
/// <summary>Transmission Control Protocol.</summary>
|
||||
Tcp
|
||||
Tcp,
|
||||
};
|
||||
|
||||
enum class FLAXENGINE_API NetworkIPVersion
|
||||
/// <summary>
|
||||
/// IP version type.
|
||||
/// </summary>
|
||||
API_ENUM() enum class NetworkIPVersion
|
||||
{
|
||||
/// <summary>Not specified.</summary>
|
||||
Undefined,
|
||||
/// <summary>Internet Protocol version 4.</summary>
|
||||
IPv4,
|
||||
/// <summary>Internet Protocol version 6.</summary>
|
||||
IPv6
|
||||
IPv6,
|
||||
};
|
||||
|
||||
struct FLAXENGINE_API NetworkSocket
|
||||
/// <summary>
|
||||
/// Network socket.
|
||||
/// </summary>
|
||||
API_STRUCT() struct FLAXENGINE_API NetworkSocket
|
||||
{
|
||||
NetworkProtocol Protocol = NetworkProtocol::Undefined;
|
||||
NetworkIPVersion IPVersion = NetworkIPVersion::Undefined;
|
||||
byte Data[8] = {};
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkSocketGroup)
|
||||
|
||||
/// <summary>Socket protocol type.</summary>
|
||||
API_FIELD() NetworkProtocol Protocol = NetworkProtocol::Undefined;
|
||||
/// <summary>Socket address IP version.</summary>
|
||||
API_FIELD() NetworkIPVersion IPVersion = NetworkIPVersion::Undefined;
|
||||
API_FIELD(Private, NoArray) byte Data[8] = {};
|
||||
};
|
||||
|
||||
struct FLAXENGINE_API NetworkAddress
|
||||
/// <summary>
|
||||
/// Network end-point.
|
||||
/// </summary>
|
||||
API_STRUCT() struct FLAXENGINE_API NetworkEndPoint
|
||||
{
|
||||
String Address;
|
||||
String Port;
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkSocketGroup)
|
||||
|
||||
/// <summary>End-point IP version.</summary>
|
||||
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
|
||||
/// <summary>
|
||||
/// Network socket options.
|
||||
/// </summary>
|
||||
API_ENUM() enum class NetworkSocketOption
|
||||
{
|
||||
/// <summary>Enables debugging info recording.</summary>
|
||||
Debug,
|
||||
@@ -81,29 +96,53 @@ enum class FLAXENGINE_API NetworkSocketOption
|
||||
IPv6Only,
|
||||
/// <summary>Retrieve the current path MTU, the socket must be connected UDP/TCP.</summary>
|
||||
Mtu,
|
||||
// <summary>Socket type, DGRAM, STREAM ..</summary>
|
||||
Type
|
||||
/// <summary>Socket type, DGRAM, STREAM ..</summary>
|
||||
Type,
|
||||
};
|
||||
|
||||
struct FLAXENGINE_API NetworkSocketState
|
||||
/// <summary>
|
||||
/// Network socket state.
|
||||
/// </summary>
|
||||
API_ENUM() enum class NetworkSocketState
|
||||
{
|
||||
bool Error = false;
|
||||
bool Invalid = false;
|
||||
bool Disconnected = false;
|
||||
bool Readable = false;
|
||||
bool Writeable = false;
|
||||
/// <summary>Nothing.</summary>
|
||||
None = 0,
|
||||
/// <summary>Socket error.</summary>
|
||||
Error = 1 << 0,
|
||||
/// <summary>Invalid request.</summary>
|
||||
Invalid = 1 << 1,
|
||||
/// <summary>Socket disconnected.</summary>
|
||||
Disconnected = 1 << 2,
|
||||
/// <summary>Socket is readable.</summary>
|
||||
Readable = 1 << 3,
|
||||
/// <summary>Socket is writable.</summary>
|
||||
Writeable = 1 << 4,
|
||||
};
|
||||
|
||||
struct FLAXENGINE_API NetworkSocketGroup
|
||||
DECLARE_ENUM_OPERATORS(NetworkSocketState);
|
||||
|
||||
/// <summary>
|
||||
/// Network sockets group.
|
||||
/// </summary>
|
||||
API_STRUCT() struct FLAXENGINE_API NetworkSocketGroup
|
||||
{
|
||||
uint32 Count = 0;
|
||||
uint32 Capacity = 0;
|
||||
byte *Data;
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(NetworkSocketGroup)
|
||||
|
||||
/// <summary>Group size.</summary>
|
||||
API_FIELD(ReadOnly) uint32 Count = 0;
|
||||
/// <summary>Group capacity.</summary>
|
||||
API_FIELD(ReadOnly) uint32 Capacity = 0;
|
||||
API_FIELD(Private) byte* Data = nullptr;
|
||||
};
|
||||
|
||||
class FLAXENGINE_API NetworkBase
|
||||
/// <summary>
|
||||
/// Low-level networking implementation interface with Berkeley sockets.
|
||||
/// </summary>
|
||||
API_CLASS(Static, Name="Network") class FLAXENGINE_API NetworkBase
|
||||
{
|
||||
public:
|
||||
static struct FLAXENGINE_API ScriptingTypeInitializer TypeInitializer;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new native socket.
|
||||
/// </summary>
|
||||
@@ -111,14 +150,14 @@ public:
|
||||
/// <param name="proto">The protocol.</param>
|
||||
/// <param name="ipv">The ip version.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
static bool CreateSocket(NetworkSocket& socket, NetworkProtocol proto, NetworkIPVersion ipv);
|
||||
API_FUNCTION() static bool CreateSocket(API_PARAM(Ref) NetworkSocket& socket, NetworkProtocol proto, NetworkIPVersion ipv);
|
||||
|
||||
/// <summary>
|
||||
/// Closes native socket.
|
||||
/// </summary>
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
static bool DestroySocket(NetworkSocket& socket);
|
||||
API_FUNCTION() static bool DestroySocket(API_PARAM(Ref) NetworkSocket& socket);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the specified socket option.
|
||||
@@ -127,16 +166,7 @@ public:
|
||||
/// <param name="option">The option.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
static bool SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool value);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the specified socket option.
|
||||
/// </summary>
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <param name="option">The option.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
static bool SetSocketOption(NetworkSocket& socket, NetworkSocketOption option, int32 value);
|
||||
API_FUNCTION() static bool SetSocketOption(API_PARAM(Ref) NetworkSocket& socket, NetworkSocketOption option, int32 value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specified socket option.
|
||||
@@ -145,16 +175,7 @@ public:
|
||||
/// <param name="option">The option.</param>
|
||||
/// <param name="value">The returned value.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
static bool GetSocketOption(NetworkSocket& socket, NetworkSocketOption option, bool* value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specified socket option.
|
||||
/// </summary>
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <param name="option">The option.</param>
|
||||
/// <param name="value">The returned value.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Connects a socket to the specified end point.
|
||||
@@ -162,7 +183,7 @@ public:
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <param name="endPoint">The end point.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
static bool ConnectSocket(NetworkSocket& socket, NetworkEndPoint& endPoint);
|
||||
API_FUNCTION() static bool ConnectSocket(API_PARAM(Ref) NetworkSocket& socket, API_PARAM(Ref) NetworkEndPoint& endPoint);
|
||||
|
||||
/// <summary>
|
||||
/// Binds a socket to the specified end point.
|
||||
@@ -170,7 +191,7 @@ public:
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <param name="endPoint">The end point.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
static bool BindSocket(NetworkSocket& socket, NetworkEndPoint& endPoint);
|
||||
API_FUNCTION() static bool BindSocket(API_PARAM(Ref) NetworkSocket& socket, API_PARAM(Ref) NetworkEndPoint& endPoint);
|
||||
|
||||
/// <summary>
|
||||
/// Listens for incoming connection.
|
||||
@@ -178,7 +199,7 @@ public:
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <param name="queueSize">Pending connection queue size.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
static bool Listen(NetworkSocket& socket, uint16 queueSize);
|
||||
API_FUNCTION() static bool Listen(API_PARAM(Ref) NetworkSocket& socket, uint16 queueSize);
|
||||
|
||||
/// <summary>
|
||||
/// Accepts a pending connection.
|
||||
@@ -187,21 +208,21 @@ public:
|
||||
/// <param name="newSocket">The newly connected socket.</param>
|
||||
/// <param name="newEndPoint">The end point of the new socket.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Checks for socket readability.
|
||||
/// </summary>
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <returns>Returns true when data is available. Otherwise false.</returns>
|
||||
static bool IsReadable(NetworkSocket& socket);
|
||||
API_FUNCTION() static bool IsReadable(API_PARAM(Ref) NetworkSocket& socket);
|
||||
|
||||
/// <summary>
|
||||
/// Checks for socket writeability.
|
||||
/// </summary>
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <returns>Returns true when data can be written. Otherwise false.</returns>
|
||||
static bool IsWritable(NetworkSocket& socket);
|
||||
API_FUNCTION() static bool IsWritable(API_PARAM(Ref) NetworkSocket& socket);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a socket group. It allocate memory based on the desired capacity.
|
||||
@@ -209,21 +230,21 @@ public:
|
||||
/// <param name="capacity">The group capacity (fixed).</param>
|
||||
/// <param name="group">The group.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
static bool CreateSocketGroup(uint32 capacity, NetworkSocketGroup& group);
|
||||
API_FUNCTION() static bool CreateSocketGroup(uint32 capacity, API_PARAM(Out) NetworkSocketGroup& group);
|
||||
|
||||
/// <summary>
|
||||
/// Destroy the socket group, and free the allocated memory.
|
||||
/// </summary>
|
||||
/// <param name="group">The group.</param>
|
||||
/// <returns>Returns true if the group is already destroyed, otherwise false.</returns>
|
||||
static bool DestroySocketGroup(NetworkSocketGroup& group);
|
||||
|
||||
API_FUNCTION() static bool DestroySocketGroup(API_PARAM(Ref) NetworkSocketGroup& group);
|
||||
|
||||
/// <summary>
|
||||
/// Updates sockets states.
|
||||
/// </summary>
|
||||
/// <param name="group">The sockets group.</param>
|
||||
/// <returns>Returns -1 on error, The number of elements where states are nonzero, otherwise 0.</returns>
|
||||
static int32 Poll(NetworkSocketGroup& group);
|
||||
API_FUNCTION() static int32 Poll(API_PARAM(Ref) NetworkSocketGroup& group);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves socket state.
|
||||
@@ -232,7 +253,7 @@ public:
|
||||
/// <param name="index">The socket index in group.</param>
|
||||
/// <param name="state">The returned state.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a socket to a group.
|
||||
@@ -240,24 +261,23 @@ public:
|
||||
/// <param name="group">The group.</param>
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <returns>Returns the socket index in group or -1 on error.</returns>
|
||||
static int32 AddSocketToGroup(NetworkSocketGroup& group, NetworkSocket& socket);
|
||||
API_FUNCTION() static int32 AddSocketToGroup(API_PARAM(Ref) NetworkSocketGroup& group, API_PARAM(Ref) NetworkSocket& socket);
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="group">The group.</param>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <param name="socket">The returned socket.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the socket at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="group">The group.</param>
|
||||
/// <param name="index">The index.</param>
|
||||
static void RemoveSocketFromGroup(NetworkSocketGroup& group, uint32 index);
|
||||
API_FUNCTION() static void RemoveSocketFromGroup(API_PARAM(Ref) NetworkSocketGroup& group, uint32 index);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the socket if present.
|
||||
@@ -265,13 +285,13 @@ public:
|
||||
/// <param name="group">The group.</param>
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <returns>Returns true if the socket is not found, otherwise false.</returns>
|
||||
static bool RemoveSocketFromGroup(NetworkSocketGroup& group, NetworkSocket& socket);
|
||||
|
||||
API_FUNCTION() static bool RemoveSocketFromGroup(API_PARAM(Ref) NetworkSocketGroup& group, API_PARAM(Ref) NetworkSocket& socket);
|
||||
|
||||
/// <summary>
|
||||
/// Clears the socket group.
|
||||
/// </summary>
|
||||
/// <param name="group">The group.</param>
|
||||
static void ClearGroup(NetworkSocketGroup& group);
|
||||
API_FUNCTION() static void ClearGroup(API_PARAM(Ref) NetworkSocketGroup& group);
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to the socket.
|
||||
@@ -279,9 +299,9 @@ public:
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <param name="data">The data to write.</param>
|
||||
/// <param name="length">The length of data.</param>
|
||||
/// <param name="endPoint">If protocol is UDP , the destination end point. Otherwise nullptr.</param>
|
||||
/// <param name="endPoint">If protocol is UDP, the destination end point. Otherwise nullptr.</param>
|
||||
/// <returns>Returns -1 on error, otherwise bytes written.</returns>
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Reads data on the socket.
|
||||
@@ -291,22 +311,23 @@ public:
|
||||
/// <param name="bufferSize">Size of the buffer.</param>
|
||||
/// <param name="endPoint">If UDP, the end point from where data is coming. Otherwise nullptr.</param>
|
||||
/// <returns>Returns -1 on error, otherwise bytes read.</returns>
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an end point.
|
||||
/// </summary>
|
||||
/// <param name="address">The address.</param>
|
||||
/// <param name="address">The network address.</param>
|
||||
/// <param name="port">The network port.</param>
|
||||
/// <param name="ipv">The ip version.</param>
|
||||
/// <param name="endPoint">The created end point.</param>
|
||||
/// <param name="bindable">True if the end point will be connected or binded.</param>
|
||||
/// <returns>Returns true on error, otherwise false.</returns>
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Remaps an ipv4 end point to an ipv6 one.
|
||||
/// </summary>
|
||||
/// <param name="endPoint">The ipv4 end point.</param>
|
||||
/// <returns>The ipv6 end point.</returns>
|
||||
static NetworkEndPoint RemapEndPointToIPv6(NetworkEndPoint& endPoint);
|
||||
API_FUNCTION() static NetworkEndPoint RemapEndPointToIPv6(API_PARAM(Ref) NetworkEndPoint& endPoint);
|
||||
};
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
partial class Platform
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if current execution in on the main thread.
|
||||
/// </summary>
|
||||
/// <returns>True if running on the main thread, otherwise false.</returns>
|
||||
public static bool IsInMainThread => CurrentThreadID == Globals.MainThreadID;
|
||||
}
|
||||
}
|
||||
79
Source/Engine/Platform/Platform.cs
Normal file
79
Source/Engine/Platform/Platform.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
partial class Platform
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if current execution in on the main thread.
|
||||
/// </summary>
|
||||
public static bool IsInMainThread => CurrentThreadID == Globals.MainThreadID;
|
||||
}
|
||||
|
||||
partial class Network
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes data to the socket.
|
||||
/// </summary>
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <param name="data">The data to write.</param>
|
||||
/// <returns>Returns -1 on error, otherwise bytes written.</returns>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to the socket.
|
||||
/// </summary>
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <param name="data">The data to write.</param>
|
||||
/// <param name="endPoint">If protocol is UDP, the destination end point.</param>
|
||||
/// <returns>Returns -1 on error, otherwise bytes written.</returns>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads data on the socket.
|
||||
/// </summary>
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <param name="buffer">The buffer.</param>
|
||||
/// <returns>Returns -1 on error, otherwise bytes read.</returns>
|
||||
[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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads data on the socket.
|
||||
/// </summary>
|
||||
/// <param name="socket">The socket.</param>
|
||||
/// <param name="buffer">The buffer.</param>
|
||||
/// <param name="endPoint">If UDP, the end point from where data is coming. Otherwise nullptr.</param>
|
||||
/// <returns>Returns -1 on error, otherwise bytes read.</returns>
|
||||
[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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "UnixNetwork.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Utilities/StringConverter.h"
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,34 +4,24 @@
|
||||
|
||||
#include "Win32Network.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include <WinSock2.h>
|
||||
#include <WS2ipdef.h>
|
||||
#include <WS2tcpip.h>
|
||||
|
||||
#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<LPWSTR>(&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<LPWSTR>(&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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user