FastEngine 0.9.4
A multiplayer oriented 2D engine made with Vulkan.
Loading...
Searching...
No Matches
C_socket.hpp
1/*
2 * Copyright 2025 Guillaume Guillet
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _FGE_C_SOCKET_HPP_INCLUDED_
18#define _FGE_C_SOCKET_HPP_INCLUDED_
19
20/*
21 * Original from : https://github.com/SFML/SFML
22 * Copyright (C) 2007-2022 Laurent Gomila
23 *
24 * Altered/Modified by Guillaume Guillet
25 */
26
27#include "FastEngine/fge_extern.hpp"
28#include "FastEngine/network/C_ipAddress.hpp"
29#include <cstdint>
30#include <vector>
31
32#define FGE_SOCKET_ETHERNET_MTU 1500
33#define FGE_SOCKET_IPV4_MIN_MTU 576
34#define FGE_SOCKET_IPV6_MIN_MTU 1280
35#define FGE_SOCKET_IPV4_HEADER_SIZE 20
36#define FGE_SOCKET_IPV6_HEADER_SIZE 40
37#define FGE_SOCKET_UDP_HEADER_SIZE 8
38
39#define FGE_SOCKET_FULL_DATAGRAM_SIZE (0xFFFF)
40#define FGE_SOCKET_IPV4_MAX_DATAGRAM_SIZE \
41 (FGE_SOCKET_FULL_DATAGRAM_SIZE - FGE_SOCKET_IPV4_HEADER_SIZE - FGE_SOCKET_UDP_HEADER_SIZE)
42#define FGE_SOCKET_IPV6_MAX_DATAGRAM_SIZE \
43 (FGE_SOCKET_FULL_DATAGRAM_SIZE - FGE_SOCKET_IPV6_HEADER_SIZE - FGE_SOCKET_UDP_HEADER_SIZE)
44#define FGE_SOCKET_IPV4_MAX_DATAGRAM_MTU_SIZE \
45 (FGE_SOCKET_IPV4_MIN_MTU - FGE_SOCKET_IPV4_HEADER_SIZE - FGE_SOCKET_UDP_HEADER_SIZE)
46#define FGE_SOCKET_IPV6_MAX_DATAGRAM_MTU_SIZE \
47 (FGE_SOCKET_IPV6_MIN_MTU - FGE_SOCKET_IPV6_HEADER_SIZE - FGE_SOCKET_UDP_HEADER_SIZE)
48#define FGE_SOCKET_IPV4_MAX_DATAGRAM_ETHMTU_SIZE \
49 (FGE_SOCKET_ETHERNET_MTU - FGE_SOCKET_IPV4_HEADER_SIZE - FGE_SOCKET_UDP_HEADER_SIZE)
50#define FGE_SOCKET_IPV6_MAX_DATAGRAM_ETHMTU_SIZE \
51 (FGE_SOCKET_ETHERNET_MTU - FGE_SOCKET_IPV6_HEADER_SIZE - FGE_SOCKET_UDP_HEADER_SIZE)
52
53#define FGE_SOCKET_TCP_DEFAULT_BUFFERSIZE 2048
54
55namespace fge::net
56{
57
58class Packet;
59
65class FGE_API Socket
66{
67public:
68#ifdef _WIN32
69 #if defined(_WIN64)
70 using SocketDescriptor = uint64_t;
71 #else
72 using SocketDescriptor = unsigned int;
73 #endif
74#else
75 using SocketDescriptor = int;
76#endif
77
82 enum class Types
83 {
84 UDP,
85 TCP,
86 TCP_LISTENER,
87 UNKNOWN
88 };
89
94 enum class Errors
95 {
96 ERR_NOERROR = 0,
97 ERR_SUCCESS = ERR_NOERROR,
98 ERR_DONE = ERR_NOERROR,
99
100 ERR_PARTIAL = 1,
101 ERR_NOTREADY = 2,
102 ERR_DISCONNECTED = 3,
103 ERR_REFUSED = 4,
104
105 ERR_ALREADYCONNECTED = 5,
106 ERR_ALREADYUSED = 6,
107 ERR_TOOMANYSOCKET = 7,
108
109 ERR_NOTINIT = 8,
110
111 ERR_INVALIDARGUMENT = 9,
112
113 ERR_UNSUCCESS = 10,
114 ERR_UNKNOWN = ERR_UNSUCCESS
115 };
116
118 {
119 struct Data
120 {
121 IpAddress _unicast;
122 };
123
124 std::string _name;
125 std::string _description;
126 uint16_t _mtu;
127 std::vector<Data> _data;
128 };
129
137 [[nodiscard]] inline Types getType() const { return this->g_type; }
145 [[nodiscard]] inline IpAddress::Types getAddressType() const { return this->g_addressType; }
153 void setAddressType(IpAddress::Types type);
154
160 virtual Errors create() = 0;
164 void close();
172 [[nodiscard]] bool isValid() const;
173
182 [[nodiscard]] Port getLocalPort() const;
191 [[nodiscard]] IpAddress getLocalAddress() const;
201 [[nodiscard]] Port getRemotePort() const;
211 [[nodiscard]] IpAddress getRemoteAddress() const;
212
218 [[nodiscard]] bool isBlocking() const;
219
226 Errors setBlocking(bool mode);
256 Errors setIpv6Only(bool mode);
270
283 Errors select(bool read, uint32_t timeoutms);
284
292 static bool initSocket();
296 static void uninitSocket();
297
310 [[nodiscard]] std::optional<uint16_t> retrieveCurrentAdapterMTU() const;
311
320 [[nodiscard]] static std::vector<AdapterInfo> getAdaptersInfo(IpAddress::Types type = IpAddress::Types::None);
321
327 [[nodiscard]] static int getPlatformSpecifiedError();
328
329 Socket& operator=(Socket const& r) = delete;
330 Socket(Socket const& r) = delete;
331
332protected:
333 explicit Socket(Types type, IpAddress::Types addressType = IpAddress::Types::Ipv4);
334 virtual ~Socket();
335
336 Types g_type;
337 IpAddress::Types g_addressType{IpAddress::Types::Ipv4};
338 SocketDescriptor g_socket;
339 bool g_isBlocking;
340};
341
347class FGE_API SocketUdp : public Socket
348{
349public:
350 explicit SocketUdp(IpAddress::Types addressType = IpAddress::Types::Ipv4);
351 SocketUdp(IpAddress::Types addressType, bool blocking, bool broadcast);
352 ~SocketUdp() override = default;
353
354 Errors create() override;
355
368 Errors connect(IpAddress const& remoteAddress, Port remotePort);
369 Errors disconnect();
380 Errors bind(Port port, IpAddress const& address);
381
393 Errors send(void const* data, std::size_t size);
403 Errors sendTo(void const* data, std::size_t size, IpAddress const& remoteAddress, Port remotePort);
414 Errors receiveFrom(void* data, std::size_t size, std::size_t& received, IpAddress& remoteAddress, Port& remotePort);
427 Errors receive(void* data, std::size_t size, std::size_t& received);
428
449 Errors sendTo(Packet& packet, IpAddress const& remoteAddress, Port remotePort);
458 Errors receiveFrom(Packet& packet, IpAddress& remoteAddress, Port& remotePort);
470
479 [[nodiscard]] static std::optional<uint16_t> retrieveAdapterMTUForDestination(IpAddress const& destination);
480
481 SocketUdp& operator=(SocketUdp&& r) noexcept;
482
483private:
484 std::vector<uint8_t> g_buffer;
485};
486
492class FGE_API SocketTcp : public Socket
493{
494public:
495 explicit SocketTcp(IpAddress::Types addressType = IpAddress::Types::Ipv4);
496 explicit SocketTcp(IpAddress::Types addressType, bool blocking);
497 ~SocketTcp() override = default;
498
504 void flush();
505
515 Errors create(SocketDescriptor sck);
524 Errors create() override;
525
534 Errors connect(IpAddress const& remoteAddress, Port remotePort, uint32_t timeoutms);
535
543 Errors send(void const* data, std::size_t size);
552 Errors send(void const* data, std::size_t size, std::size_t& sent);
561 Errors receive(void* data, std::size_t size, std::size_t& received);
562 Errors receive(void* data, std::size_t size, std::size_t& received, uint32_t timeoutms);
563
581
590 Errors sendAndReceive(Packet& sendPacket, Packet& receivePacket, uint32_t timeoutms);
598 Errors receive(Packet& packet, uint32_t timeoutms);
599
600 SocketTcp& operator=(SocketTcp&& r) noexcept;
601
602private:
603 std::size_t g_receivedSize;
604 std::size_t g_wantedSize;
605 std::vector<uint8_t> g_buffer;
606};
607
613class FGE_API SocketListenerTcp : public Socket
614{
615public:
616 explicit SocketListenerTcp(IpAddress::Types addressType = IpAddress::Types::Ipv4);
617 explicit SocketListenerTcp(IpAddress::Types addressType, bool blocking);
618 ~SocketListenerTcp() override = default;
619
625 Errors create() override;
626
634 Errors listen(Port port, IpAddress const& address);
642
643 SocketListenerTcp& operator=(SocketListenerTcp&& r) noexcept;
644};
645
646} // namespace fge::net
647
648#endif // _FGE_C_SOCKET_HPP_INCLUDED_
A class to represent an IP address.
Definition C_ipAddress.hpp:57
Definition C_packet.hpp:52
Errors accept(SocketTcp &socket)
Accept a new connection.
Errors create() override
Create the socket listener.
Errors listen(Port port, IpAddress const &address)
Start listening for new connections from a port.
A wrapper for TCP sockets inheriting from Socket.
Definition C_socket.hpp:493
Errors receive(Packet &packet, uint32_t timeoutms)
Receive a packet from the connected remote address with a timeout.
Errors create() override
Create a socket.
void flush()
Flush the internal data buffer.
Errors send(Packet &packet)
Send a Packet to the connected remote address.
Errors receive(void *data, std::size_t size, std::size_t &received)
Receive data from the connected remote address.
Errors sendAndReceive(Packet &sendPacket, Packet &receivePacket, uint32_t timeoutms)
Utility function to send and receive data.
Errors connect(IpAddress const &remoteAddress, Port remotePort, uint32_t timeoutms)
Connect to a remote address.
Errors create(SocketDescriptor sck)
Create the socket with an existing descriptor.
Errors send(void const *data, std::size_t size)
Send data to the connected remote address.
Errors send(void const *data, std::size_t size, std::size_t &sent)
Send data to the connected remote address.
Errors receive(Packet &packet)
Receive a Packet from the connected remote address.
Errors bind(Port port, IpAddress const &address)
Bind the socket to a local address and port.
Errors sendTo(void const *data, std::size_t size, IpAddress const &remoteAddress, Port remotePort)
Send data to the specified address.
Errors send(Packet &packet)
Send a Packet to the connected remote address.
Errors send(void const *data, std::size_t size)
Send data to the connected remote address.
Errors create() override
Create a new socket.
Errors connect(IpAddress const &remoteAddress, Port remotePort)
Connect the socket to a remote address and port.
Errors sendTo(Packet &packet, IpAddress const &remoteAddress, Port remotePort)
Send a Packet to the specified address.
Errors receiveFrom(void *data, std::size_t size, std::size_t &received, IpAddress &remoteAddress, Port &remotePort)
Receive data from an unspecified remote address.
Errors receive(void *data, std::size_t size, std::size_t &received)
Receive data from the connected remote address.
Errors receiveFrom(Packet &packet, IpAddress &remoteAddress, Port &remotePort)
Receive a Packet from an unspecified remote address.
Errors receive(Packet &packet)
Receive a Packet from the connected remote address.
static std::optional< uint16_t > retrieveAdapterMTUForDestination(IpAddress const &destination)
Helper to retrieve the MTU of the adapter used to reach the destination ip address.
Errors setBlocking(bool mode)
Set the blocking mode of the socket.
IpAddress::Types getAddressType() const
Get the address type of the socket.
Definition C_socket.hpp:145
std::optional< uint16_t > retrieveCurrentAdapterMTU() const
Retrieve the current adapter MTU.
Errors setBroadcastOption(bool mode)
Set if the socket support broadcast.
Errors
The error codes.
Definition C_socket.hpp:95
Errors setReuseAddress(bool mode)
Set if the socket reuse the address.
Port getLocalPort() const
Get the local port of the socket.
static int getPlatformSpecifiedError()
Get the last platform specific error code.
Errors setDontFragment(bool mode)
Set if the socket should append DF flag to the packet.
Types getType() const
Get the type of the socket.
Definition C_socket.hpp:137
void close()
Close the socket.
void setAddressType(IpAddress::Types type)
Set the address type of the socket.
bool isValid() const
Check if the socket is valid.
Errors setIpv6Only(bool mode)
Set if ipv6 socket should only use ipv6.
Port getRemotePort() const
Get the remote port of the socket.
Errors select(bool read, uint32_t timeoutms)
Check the socket for readability or writability.
Types
The possible types of sockets.
Definition C_socket.hpp:83
static bool initSocket()
Init the low-level socket library.
IpAddress getRemoteAddress() const
Get the remote address of the socket.
virtual Errors create()=0
Create a new socket.
static void uninitSocket()
Shutdown the low-level socket library.
IpAddress getLocalAddress() const
Get the local address of the socket.
static std::vector< AdapterInfo > getAdaptersInfo(IpAddress::Types type=IpAddress::Types::None)
Retrieve adapters information.
bool isBlocking() const
Check if the socket is in blocking mode.
Definition C_socket.hpp:120
Definition C_socket.hpp:118