Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
Socket.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Foundation/Compiler.h"
5#ifndef SC_EXPORT_LIBRARY_SOCKET
6#define SC_EXPORT_LIBRARY_SOCKET 0
7#endif
8#define SC_SOCKET_EXPORT SC_COMPILER_LIBRARY_EXPORT(SC_EXPORT_LIBRARY_SOCKET)
9
10#include "../Foundation/AlignedStorage.h"
11#include "../Foundation/Result.h"
12#include "../Foundation/StringSpan.h"
13#include "../Foundation/UniqueHandle.h"
14
15namespace SC
16{
19
20namespace detail
21{
22
24#if SC_PLATFORM_WINDOWS
25
26struct SC_SOCKET_EXPORT SocketDescriptorDefinition
27{
28 using Handle = size_t; // SOCKET
29 static Result releaseHandle(Handle& handle);
30
31 static constexpr Handle Invalid = ~static_cast<Handle>(0); // INVALID_SOCKET
32};
33
34#else
35
36struct SC_SOCKET_EXPORT SocketDescriptorDefinition
37{
38 using Handle = int; // fd
39 static Result releaseHandle(Handle& handle);
40
41 static constexpr Handle Invalid = -1; // invalid fd
42};
43
44#endif
45} // namespace detail
46
48struct SC_SOCKET_EXPORT SocketFlags
49{
52 {
54 Blocking
55 };
56
59 {
61 Inheritable
62 };
63
70
73 {
75 SocketDgram
76 };
77
84
87 {
88 ShutdownBoth
89 };
90
91 private:
92 friend struct SocketDescriptor;
93 friend struct SocketIPAddressInternal;
94 [[nodiscard]] static AddressFamily AddressFamilyFromInt(int value);
95 [[nodiscard]] static unsigned char toNative(AddressFamily family);
96
97 [[nodiscard]] static int toNative(SocketType family);
98 [[nodiscard]] static int toNative(ProtocolType family);
99};
100
105struct SC_SOCKET_EXPORT SocketIPAddress
106{
108 static constexpr int MAX_ASCII_STRING_LENGTH = 46;
109
111 using AsciiBuffer = char[MAX_ASCII_STRING_LENGTH];
112
115 SocketIPAddress(SocketFlags::AddressFamily addressFamily = SocketFlags::AddressFamilyIPV4);
116
120
123 [[nodiscard]] uint16_t getPort() const;
124
129 Result fromAddressPort(StringSpan interfaceAddress, uint16_t port);
130
132 [[nodiscard]] uint32_t sizeOfHandle() const;
133
135 [[nodiscard]] bool isValid() const;
136
141 [[nodiscard]] bool toString(Span<char> inputSpan, StringSpan& outputSpan) const;
142
145
146 private:
147 friend struct SocketServer;
148 friend struct SocketClient;
149
150 struct Internal;
151};
152
158struct SC_SOCKET_EXPORT SocketDescriptor : public UniqueHandle<detail::SocketDescriptorDefinition>
159{
168 SocketFlags::SocketType socketType = SocketFlags::SocketStream,
169 SocketFlags::ProtocolType protocol = SocketFlags::ProtocolTcp,
170 SocketFlags::BlockingType blocking = SocketFlags::Blocking,
171 SocketFlags::InheritableType inheritable = SocketFlags::NonInheritable);
172
176 Result isInheritable(bool& value) const;
177
182
186 Result setBlocking(bool value);
187
192
197
201 Result setTcpNoDelay(bool tcpNoDelay);
202
206 Result setBroadcast(bool enableBroadcast);
207
212 Result joinMulticastGroup(const SocketIPAddress& multicastAddress, const SocketIPAddress& interfaceAddress);
213
218 Result leaveMulticastGroup(const SocketIPAddress& multicastAddress, const SocketIPAddress& interfaceAddress);
219
224 Result setMulticastLoopback(SocketFlags::AddressFamily addressFamily, bool enableLoopback);
225
231
236};
237
242struct SC_SOCKET_EXPORT SocketServer
243{
244 enum class BindReuseAddress : uint8_t
245 {
246 Disabled,
247 Enabled,
248 };
249
250 enum class BindStatus : uint8_t
251 {
252 None,
253 AddressInUse,
254 };
255
258 SocketServer(SocketDescriptor& socket) : socket(socket) {}
259
263
269 Result bind(SocketIPAddress nativeAddress, BindReuseAddress reuseAddress = BindReuseAddress::Enabled,
270 BindStatus* outStatus = nullptr);
271
276 Result listen(uint32_t numberOfWaitingConnections);
277
283
284 private:
285 SocketDescriptor& socket;
286};
287
298struct SC_SOCKET_EXPORT SocketClient
299{
302 SocketClient(const SocketDescriptor& socket) : socket(socket) {}
303
310
315
320
326
333
334 private:
335 const SocketDescriptor& socket;
336};
337
342struct SC_SOCKET_EXPORT SocketDNS
343{
351 [[nodiscard]] static Result resolveDNS(StringSpan host, Span<char>& ipAddress);
352};
353
355struct SC_SOCKET_EXPORT SocketNetworking
356{
358 static void initNetworking();
359
361 static void shutdownNetworking();
362
365 [[nodiscard]] static bool isNetworkingInited();
366
367 private:
368 struct Internal;
369};
370
372} // namespace SC
unsigned short uint16_t
Platform independent (2) bytes unsigned int.
Definition PrimitiveTypes.h:28
unsigned char uint8_t
Platform independent (1) byte unsigned int.
Definition PrimitiveTypes.h:27
decltype(sizeof(0)) size_t
Platform independent unsigned size type.
Definition PrimitiveTypes.h:45
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:29
long long int64_t
Platform independent (8) bytes signed int.
Definition PrimitiveTypes.h:41
A buffer of bytes with given alignment.
Definition AlignedStorage.h:29
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition Result.h:13
Use a SocketDescriptor as a client (example a TCP or UDP socket client).
Definition Socket.h:299
Result read(Span< char > data, Span< char > &readData)
Read bytes from this socket blocking until they're actually received.
SocketClient(const SocketDescriptor &socket)
Constructs this SocketClient from a SocketDescriptor (already created with SocketDescriptor::create)
Definition Socket.h:302
Result connect(StringSpan address, uint16_t port)
Connect to a given address and port combination.
Result connect(SocketIPAddress ipAddress)
Connect to a given address and port combination.
Result readWithTimeout(Span< char > data, Span< char > &readData, int64_t timeout)
Read bytes from this socket blocking until they're actually received or timeout occurs.
Result write(Span< const char > data)
Writes bytes to this socket.
Synchronous DNS Resolution.
Definition Socket.h:343
static Result resolveDNS(StringSpan host, Span< char > &ipAddress)
Resolve an host string to an ip address (blocking until DNS response arrives)
Low-level OS socket handle.
Definition Socket.h:159
Result setMulticastHops(SocketFlags::AddressFamily addressFamily, int hops)
Specifies the default TTL or hop limit for outgoing multicast datagrams.
Result shutdown(SocketFlags::ShutdownType shutdownType)
Shuts down the socket for reading, writing, or both.
Result setTcpNoDelay(bool tcpNoDelay)
Disables Nagle's algorithm for low-latency communication.
Result setBroadcast(bool enableBroadcast)
Enables or disables broadcast on this socket (for UDP)
Result setMulticastOutboundInterface(const SocketIPAddress &interfaceAddress)
Specifies the default local network interface for outgoing multicast datagrams.
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 leaveMulticastGroup(const SocketIPAddress &multicastAddress, const SocketIPAddress &interfaceAddress)
Leaves a previously joined IPv4 or IPv6 multicast group on a specific interface.
Result setMulticastLoopback(SocketFlags::AddressFamily addressFamily, bool enableLoopback)
Controls whether multicast traffic is sent back to the local host.
Result setInheritable(bool value)
Changes the inheritable flag for this socket.
Result joinMulticastGroup(const SocketIPAddress &multicastAddress, const SocketIPAddress &interfaceAddress)
Joins an IPv4 or IPv6 multicast group on a specific interface.
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 SocketDescriptor 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 Socket.h:49
SocketType
Sets the socket type, if it's a Datagram (for UDP) or Streaming (for TCP and others)
Definition Socket.h:73
@ SocketStream
Sets the socket type as Streaming type (for TCP and others)
Definition Socket.h:74
AddressFamily
Sets the address family of an IP Address (IPv4 or IPV6)
Definition Socket.h:66
@ AddressFamilyIPV6
IP Address is IPV6.
Definition Socket.h:68
@ AddressFamilyIPV4
IP Address is IPV4.
Definition Socket.h:67
InheritableType
Sets the socket inheritable behaviour for child processes.
Definition Socket.h:59
@ NonInheritable
SocketDescriptor will not be inherited by child processes.
Definition Socket.h:60
ShutdownType
Sets the type of shutdown to perform.
Definition Socket.h:87
BlockingType
Sets the socket as blocking / nonblocking mode.
Definition Socket.h:52
@ NonBlocking
SocketDescriptor is in non-blocking mode.
Definition Socket.h:53
ProtocolType
Sets the socket protocol type.
Definition Socket.h:80
@ ProtocolUdp
The protocol is UDP.
Definition Socket.h:82
@ ProtocolTcp
The protocol is TCP.
Definition Socket.h:81
Native representation of an IP Address.
Definition Socket.h:106
bool toString(Span< char > inputSpan, StringSpan &outputSpan) const
Returns the text representation of this SocketIPAddress.
uint16_t getPort() const
Get port of this ip address.
char[MAX_ASCII_STRING_LENGTH] AsciiBuffer
Buffer for storing the ASCII representation of an IP Address.
Definition Socket.h:111
Result fromAddressPort(StringSpan interfaceAddress, uint16_t port)
Builds this SocketIPAddress parsing given address string and port.
SocketFlags::AddressFamily getAddressFamily() const
Get Address family of this ip address (IPV4 or IPV6)
uint32_t sizeOfHandle() const
Size of the native IP Address representation.
SocketIPAddress(SocketFlags::AddressFamily addressFamily=SocketFlags::AddressFamilyIPV4)
Constructs an ip address from a given family (IPV4 or IPV6)
bool isValid() const
Checks if this is a valid IPV4 or IPV6 address.
Networking globals initialization (Winsock2 WSAStartup)
Definition Socket.h:356
static void initNetworking()
Initializes Winsock2 on Windows (WSAStartup)
static void shutdownNetworking()
Shutdowns Winsock2 on Windows (WSAStartup)
static bool isNetworkingInited()
Check if initNetworking has been previously called.
Use a SocketDescriptor as a Server (example TCP or UDP Socket Server).
Definition Socket.h:243
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 Socket.h:258
Result bind(SocketIPAddress nativeAddress, BindReuseAddress reuseAddress=BindReuseAddress::Enabled, BindStatus *outStatus=nullptr)
Binds this socket to a given address / port combination.
Result close()
Calls SocketDescriptor::close.
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:29
An read-only view over a string (to avoid including Strings library when parsing is not needed).
Definition StringSpan.h:37
Move only handle that has a special tag value flagging its invalid state.
Definition UniqueHandle.h:27