Sane C++ Libraries
C++ Platform Abstraction Libraries
SocketDescriptor.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Foundation/AlignedStorage.h"
5#include "../Foundation/Result.h"
6#include "../Foundation/Span.h"
7#include "../Foundation/UniqueHandle.h"
8#include "../Strings/StringView.h"
9#include "../Time/Time.h" // Milliseconds
10
11namespace SC
12{
13struct String;
14} // namespace SC
15
16namespace SC
17{
18struct SC_COMPILER_EXPORT SocketDescriptor;
19struct SocketFlags;
20struct SocketIPAddress;
21struct SocketNetworking;
22struct SocketClient;
23struct SocketServer;
24struct SocketDNS;
25namespace detail
26{
27struct SocketDescriptorDefinition;
28}
29} // namespace SC
30
38
41
43#if SC_PLATFORM_WINDOWS
44
45struct SC::detail::SocketDescriptorDefinition
46{
47 using Handle = size_t; // SOCKET
48 static Result releaseHandle(Handle& handle);
49
50 static constexpr Handle Invalid = ~static_cast<Handle>(0); // INVALID_SOCKET
51};
52
53#else
54
55struct SC::detail::SocketDescriptorDefinition
56{
57 using Handle = int; // fd
58 static Result releaseHandle(Handle& handle);
59
60 static constexpr Handle Invalid = -1; // invalid fd
61};
62
63#endif
64
67{
70 {
73 };
74
77 {
80 };
81
84 {
87 };
88
91 {
94 };
95
98 {
101 };
102
103 private:
104 friend struct SocketDescriptor;
105 friend struct SocketIPAddressInternal;
106 [[nodiscard]] static AddressFamily AddressFamilyFromInt(int value);
107 [[nodiscard]] static unsigned char toNative(AddressFamily family);
108 [[nodiscard]] static SocketType SocketTypeFromInt(int value);
109 [[nodiscard]] static int toNative(SocketType family);
110
111 [[nodiscard]] static ProtocolType ProtocolTypeFromInt(int value);
112 [[nodiscard]] static int toNative(ProtocolType family);
113};
114
120{
124 : addressFamily(addressFamily)
125 {}
126
129 [[nodiscard]] SocketFlags::AddressFamily getAddressFamily() { return addressFamily; }
130
135 [[nodiscard]] Result fromAddressPort(StringView interfaceAddress, uint16_t port);
136
137 friend struct SocketServer;
138 friend struct SocketClient;
139
140 uint32_t sizeOfHandle() const;
141
142 AlignedStorage<28> handle = {};
143
144 private:
146 struct Internal;
147};
148
153struct SC::SocketDescriptor : public UniqueHandle<detail::SocketDescriptorDefinition>
154{
162 [[nodiscard]] Result create(SocketFlags::AddressFamily addressFamily,
167
171 [[nodiscard]] Result isInheritable(bool& value) const;
172
176 [[nodiscard]] Result setInheritable(bool value);
177
181 [[nodiscard]] Result setBlocking(bool value);
182
186 [[nodiscard]] Result getAddressFamily(SocketFlags::AddressFamily& addressFamily) const;
187};
188
194{
197 SocketServer(SocketDescriptor& socket) : socket(socket) {}
198
201 [[nodiscard]] Result close();
202
206 [[nodiscard]] Result bind(SocketIPAddress nativeAddress);
207
212 [[nodiscard]] Result listen(uint32_t numberOfWaitingConnections);
213
218 [[nodiscard]] Result accept(SocketFlags::AddressFamily addressFamily, SocketDescriptor& newClient);
219
220 private:
221 SocketDescriptor& socket;
222};
223
235{
238 SocketClient(const SocketDescriptor& socket) : socket(socket) {}
239
245 [[nodiscard]] Result connect(StringView address, uint16_t port);
246
250 [[nodiscard]] Result connect(SocketIPAddress ipAddress);
251
255 [[nodiscard]] Result write(Span<const char> data);
256
261 [[nodiscard]] Result read(Span<char> data, Span<char>& readData);
262
268 [[nodiscard]] Result readWithTimeout(Span<char> data, Span<char>& readData, Time::Milliseconds timeout);
269
270 private:
271 const SocketDescriptor& socket;
272};
273
279{
287 [[nodiscard]] static Result resolveDNS(StringView host, String& ipAddress);
288};
289
292{
295 [[nodiscard]] static Result initNetworking();
296
299 [[nodiscard]] static Result shutdownNetworking();
300
303 [[nodiscard]] static bool isNetworkingInited();
304
305 private:
306 struct Internal;
307};
308
#define SC_COMPILER_EXPORT
Macro for symbol visibility in non-MSVC compilers.
Definition: Compiler.h:78
unsigned long size_t
Platform independent unsigned size type.
Definition: PrimitiveTypes.h:56
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition: PrimitiveTypes.h:38
unsigned short uint16_t
Platform independent (2) bytes unsigned int.
Definition: PrimitiveTypes.h:37
A buffer of bytes with given alignment.
Definition: AlignedStorage.h:25
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition: Result.h:11
Use a SocketDescriptor as a client (example a TCP or UDP socket client).
Definition: SocketDescriptor.h:235
Result read(Span< char > data, Span< char > &readData)
Read bytes from this socket blocking until they're actually received.
Result readWithTimeout(Span< char > data, Span< char > &readData, Time::Milliseconds timeout)
Read bytes from this socket blocking until they're actually received or timeout occurs.
SocketClient(const SocketDescriptor &socket)
Constructs this SocketClient from a SocketDescriptor (already created with SocketDescriptor::create)
Definition: SocketDescriptor.h:238
Result connect(SocketIPAddress ipAddress)
Connect to a given address and port combination.
Result write(Span< const char > data)
Writes bytes to this socket.
Result connect(StringView address, uint16_t port)
Connect to a given address and port combination.
Synchronous DNS Resolution.
Definition: SocketDescriptor.h:279
static Result resolveDNS(StringView host, String &ipAddress)
Resolve an host string to an ip address (blocking until DNS response arrives)
Low-level OS socket handle.
Definition: SocketDescriptor.h:154
Result isInheritable(bool &value) const
Check if socket is inheritable by child processes.
Result setBlocking(bool value)
Changes the blocking flag for this socket (if IO reads / writes should be blocking or not)
Result setInheritable(bool value)
Changes the inheritable flag for this socket.
Result create(SocketFlags::AddressFamily addressFamily, SocketFlags::SocketType socketType=SocketFlags::SocketStream, SocketFlags::ProtocolType protocol=SocketFlags::ProtocolTcp, SocketFlags::BlockingType blocking=SocketFlags::Blocking, SocketFlags::InheritableType inheritable=SocketFlags::NonInheritable)
Creates a new Socket Descriptor of given family, type, protocol.
Result getAddressFamily(SocketFlags::AddressFamily &addressFamily) const
Get address family (IPV4 / IPV6) of this socket.
Flags for SocketDescriptor (Blocking / Inheritable, IPVx, SocketType)
Definition: SocketDescriptor.h:67
SocketType
Sets the socket type, if it's a Datagram (for UDP) or Streaming (for TCP and others)
Definition: SocketDescriptor.h:91
@ SocketStream
Sets the socket type as Streaming type (for TCP and others)
Definition: SocketDescriptor.h:92
@ SocketDgram
Sets the socket type as Streaming type (for UDP)
Definition: SocketDescriptor.h:93
AddressFamily
Sets the address family of an IP Address (IPv4 or IPV6)
Definition: SocketDescriptor.h:84
@ AddressFamilyIPV6
IP Address is IPV6.
Definition: SocketDescriptor.h:86
@ AddressFamilyIPV4
IP Address is IPV4.
Definition: SocketDescriptor.h:85
InheritableType
Sets the socket inheritable behaviour for child processes.
Definition: SocketDescriptor.h:77
@ NonInheritable
Socket will not be inherited by child processes.
Definition: SocketDescriptor.h:78
@ Inheritable
Socket will be inherited by child processes.
Definition: SocketDescriptor.h:79
BlockingType
Sets the socket as blocking / nonblocking mode.
Definition: SocketDescriptor.h:70
@ NonBlocking
Socket is in non-blocking mode.
Definition: SocketDescriptor.h:71
@ Blocking
Socket is in blocking mode.
Definition: SocketDescriptor.h:72
ProtocolType
Sets the socket protocol type.
Definition: SocketDescriptor.h:98
@ ProtocolUdp
The protocol is UDP.
Definition: SocketDescriptor.h:100
@ ProtocolTcp
The protocol is TCP.
Definition: SocketDescriptor.h:99
Native representation of an IP Address.
Definition: SocketDescriptor.h:120
Result fromAddressPort(StringView interfaceAddress, uint16_t port)
Builds this SocketIPAddress parsing given address string and port.
SocketFlags::AddressFamily getAddressFamily()
Get Address family of this ip address (IPV4 or IPV6)
Definition: SocketDescriptor.h:129
SocketIPAddress(SocketFlags::AddressFamily addressFamily=SocketFlags::AddressFamilyIPV4)
Constructs an ip address from a given family (IPV4 or IPV6)
Definition: SocketDescriptor.h:123
Networking globals initialization (Winsock2 WSAStartup)
Definition: SocketDescriptor.h:292
static Result shutdownNetworking()
Shutdowns Winsock2 on Windows (WSAStartup)
static bool isNetworkingInited()
Check if initNetworking has been previously called.
static Result initNetworking()
Initializes Winsock2 on Windows (WSAStartup)
Use a SocketDescriptor as a Server (example TCP or UDP Socket Server).
Definition: SocketDescriptor.h:194
Result listen(uint32_t numberOfWaitingConnections)
Start listening for incoming connections at a specific address / port combination (after bind)
SocketServer(SocketDescriptor &socket)
Build a SocketServer from a SocketDescriptor (already created with SocketDescriptor::create)
Definition: SocketDescriptor.h:197
Result close()
Calls SocketDescriptor::close.
Result bind(SocketIPAddress nativeAddress)
Binds this socket to a given address / port combination.
Result accept(SocketFlags::AddressFamily addressFamily, SocketDescriptor &newClient)
Accepts a new client, blocking while waiting for it.
View over a contiguous sequence of items (pointer + size in elements).
Definition: Span.h:21
A non-modifiable owning string with associated encoding.
Definition: String.h:30
Non-owning view over a range of characters with UTF Encoding.
Definition: StringView.h:47
Type-safe wrapper of uint64 used to represent milliseconds.
Definition: Time.h:29
Move only handle that has a special tag value flagging its invalid state.
Definition: UniqueHandle.h:67