MXVK Vulkan Framework 0.24.0
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
socket.cpp
Go to the documentation of this file.
2#include <exception>
3#include <cstring>
4#include <format>
5#include <iostream>
6#include <string>
7namespace mxnetwork {
8
9 bool SocketAddress::operator==(const SocketAddress &other) const {
10 return value.length == other.value.length && value.length > 0 &&
11 std::memcmp(&value.storage, &other.value.storage, static_cast<std::size_t>(value.length)) == 0;
12 }
13
15#ifdef _WIN32
16 WSADATA wsaData;
17 int err = WSAStartup(MAKEWORD(2, 2), &wsaData);
18 if (err != 0) {
19 fprintf(stderr, "WSAStartup failed with error: %d\n", err);
20 exit(1);
21 }
22#endif
23 }
24
26#ifdef _WIN32
27 WSACleanup();
28#endif
29 }
30
32
33 Socket::Socket(SocketType stype) noexcept {
34 type = stype;
35 if (mx_socket_init(&sock))
36 return;
37 else
39 sock.sockfd = NULL_SOCKET;
40 }
41
42 Socket::~Socket() noexcept {
43 if (mx_socket_valid(&sock)) {
44 close();
45 }
46 }
47
49 if (!mx_socket_init(&sock))
50 throw Exception("Error on socket init.\n");
51
52 sock.sockfd = sockfd;
53 sock.addrlen = 0;
54 sock.blocking = false;
55 type = stype;
56 }
57
58 Socket::Socket(const MXSocket &s, SocketType stype) noexcept {
59 type = stype;
60 setsocket(s);
61 }
62
63 Socket::Socket(Socket &&s) noexcept {
64 type = s.type;
65 setsocket(s.sock);
66 s.sock.sockfd = NULL_SOCKET;
67 }
68
70 if (this != &s) {
71 type = s.type;
73 ::mx_close_socket(sock.sockfd);
74 setsocket(s.sock);
75 s.sock.sockfd = NULL_SOCKET;
76 }
77 return *this;
78 }
79
80 bool Socket::connect(const std::string_view host, const std::string_view port) {
82 return mx_socket_connect(&sock, std::string(host).c_str(), std::string(port).c_str(), SOCK_STREAM);
83 else if (type == SocketType::TYPE_INET6)
84 return mx_socket_ipv6_connect(&sock, std::string(host).c_str(), std::string(port).c_str(), SOCK_STREAM);
86 return mx_socket_connect(&sock, std::string(host).c_str(), std::string(port).c_str(), SOCK_DGRAM);
88 return mx_socket_ipv6_connect(&sock, std::string(host).c_str(), std::string(port).c_str(), SOCK_DGRAM);
89 return false;
90 }
91
92 bool Socket::connect_unix(const std::string_view path) {
94 return mx_socket_unix_connect(&sock, std::string(path).c_str(), SOCK_STREAM);
96 return mx_socket_unix_connect(&sock, std::string(path).c_str(), SOCK_DGRAM);
97 return false;
98 }
99
100 bool Socket::listen(std::string_view port, int backlog) {
102 return mx_socket_listen(&sock, std::string(port).c_str(), backlog, SOCK_STREAM);
103 else if (type == SocketType::TYPE_INET6)
104 return mx_socket_ipv6_listen(&sock, std::string(port).c_str(), backlog, SOCK_STREAM);
106 return mx_socket_listen(&sock, std::string(port).c_str(), backlog, SOCK_DGRAM);
108 return mx_socket_ipv6_listen(&sock, std::string(port).c_str(), backlog, SOCK_DGRAM);
109 return false;
110 }
111
112 bool Socket::listen_unix(std::string_view path, int backlog) {
114 return mx_socket_unix_listen(&sock, std::string(path).c_str(), backlog, SOCK_STREAM);
116 return mx_socket_unix_listen(&sock, std::string(path).c_str(), backlog, SOCK_DGRAM);
117 return false;
118 }
119
120 [[nodiscard]] std::optional<Socket> Socket::accept() {
121 MXSocket newsocket;
122 if (!mx_socket_init(&newsocket))
123 return std::nullopt;
124
125 if (mx_socket_accept(&sock, &newsocket)) {
126 return Socket(newsocket, type);
127 }
128
129 if (!mx_socket_valid(&sock))
130 return std::nullopt;
131
133 return std::nullopt;
134
135 throw Exception("Error accept socket failed.\n");
136 }
137
138 bool Socket::bind(std::string_view port) {
139 bool bound = false;
141 bound = mx_socket_bind(&sock, std::string(port).c_str());
143 bound = mx_socket_ipv6_bind(&sock, std::string(port).c_str());
144 else
145 bound = mx_socket_bind(&sock, std::string(port).c_str());
146
147 if (!bound) {
148 throw Exception("Could not bind UDP socket.");
149 }
150 return true;
151 }
152
153 bool Socket::bind_unix(std::string_view path) {
154 if (!mx_socket_unix_bind(&sock, std::string(path).c_str()))
155 return false;
156 return true;
157 }
158
159 bool Socket::setblocking(bool block) {
160 return mx_socket_set_blocking(&sock, block);
161 }
162
163 [[nodiscard]] bool Socket::valid() const {
164 return mx_socket_valid(&sock);
165 }
166
167 [[nodiscard]] bool Socket::is_open() const {
168 return mx_socket_is_open(&sock);
169 }
170
172 if (mx_socket_valid(&sock)) {
173 std::cout << "Socket: " << sock.sockfd << " closed.\n";
175 }
177 }
178
179 [[nodiscard]] SocketType Socket::socket_type() const {
180 return type;
181 }
182
183 [[nodiscard]] mx_socket_fd Socket::sockfd() const {
184 return sock.sockfd;
185 }
186
187 ssize_t Socket::read(void *buf, size_t bytes, int flags) {
188 return mx_socket_read(&sock, buf, bytes, flags);
189 }
190
191 bool Socket::readline(char **buffer, size_t *len) {
192 return mx_socket_readline(&sock, buffer, len);
193 }
194
195 ssize_t Socket::write(const void *buf, size_t bytes, int flags) {
196 return mx_socket_send(&sock, buf, bytes, flags);
197 }
198
199 ssize_t Socket::read_all(void *buf, size_t bytes) {
200 return mx_socket_read_all(&sock, buf, bytes);
201 }
202
203 ssize_t Socket::write_all(const void *buf, size_t bytes) {
204 return mx_socket_write_all(&sock, buf, bytes);
205 }
206
207 ssize_t Socket::sendto(const void *buf, size_t bytes) {
209 return mx_socket_sendto(&sock, buf, bytes);
211 return mx_socket_ipv6_sendto(&sock, buf, bytes);
213 return mx_socket_unix_sendto(&sock, buf, bytes);
214 return 0;
215 }
216 ssize_t Socket::recvfrom(void *buf, size_t bytes) {
218 return mx_socket_recvfrom(&sock, buf, bytes);
220 return mx_socket_ipv6_recvfrom(&sock, buf, bytes);
222 return mx_socket_unix_recvfrom(&sock, buf, bytes);
223 return 0;
224 }
225
226 ssize_t Socket::recvfrom(void *buf, size_t bytes, SocketAddress &address) {
227 return mx_socket_recvfrom_address(&sock, buf, bytes, &address.value);
228 }
229
230 ssize_t Socket::sendto(const void *buf, size_t bytes, const SocketAddress &address) {
231 return mx_socket_sendto_address(&sock, buf, bytes, &address.value);
232 }
233
234 void Socket::setsocket(const MXSocket &s) {
235 if (!mx_socket_init(&sock))
236 return;
237 sock.sockfd = s.sockfd;
239 sock.addrlen = s.addrlen;
241 size_t len_size = (static_cast<size_t>(s.addrlen) > sizeof(sock.inet)) ? sizeof(sock.inet) : static_cast<size_t>(s.addrlen);
242 memcpy(&sock.inet, &s.inet, len_size);
244 size_t len_size = (static_cast<size_t>(s.addrlen) > sizeof(sock.inet6)) ? sizeof(sock.inet6) : static_cast<size_t>(s.addrlen);
245 memcpy(&sock.inet6, &s.inet6, len_size);
247 sock.sun = s.sun;
248 }
249} // namespace mxnetwork
Lightweight exception wrapper for MXNetwork failures.
Definition exception.hpp:11
bool listen_unix(std::string_view path, int backlog)
Start listening on a UNIX-domain socket path.
Definition socket.cpp:112
ssize_t write_all(const void *buf, size_t bytes)
Write exactly the requested number of bytes.
Definition socket.cpp:203
ssize_t write(const void *buf, size_t bytes, int flags)
Write bytes to the socket.
Definition socket.cpp:195
void close()
Close the socket if it is open.
Definition socket.cpp:171
bool valid() const
Return true when the socket handle is valid.
Definition socket.cpp:163
bool is_open() const
Return true when the socket is open.
Definition socket.cpp:167
bool bind_unix(std::string_view path)
Bind a UNIX-domain socket to a local path.
Definition socket.cpp:153
bool readline(char **buffer, size_t *len)
Read a line of text from the socket.
Definition socket.cpp:191
SocketType socket_type() const
Return the socket family and transport type.
Definition socket.cpp:179
~Socket() noexcept
Destroy the socket wrapper and close the socket if needed.
Definition socket.cpp:42
ssize_t sendto(const void *buf, size_t bytes)
Send a datagram using the configured socket type.
Definition socket.cpp:207
Socket() noexcept
Construct an invalid socket wrapper.
Definition socket.cpp:31
bool bind(std::string_view port)
Bind an Internet socket to a local port.
Definition socket.cpp:138
bool listen(std::string_view port, int backlog)
Start listening on an Internet port.
Definition socket.cpp:100
SocketType type
Definition socket.hpp:204
std::optional< Socket > accept()
Accept an incoming connection.
Definition socket.cpp:120
bool setblocking(bool block)
Toggle blocking mode.
Definition socket.cpp:159
ssize_t read_all(void *buf, size_t bytes)
Read exactly the requested number of bytes.
Definition socket.cpp:199
ssize_t read(void *buf, size_t bytes, int flags)
Read bytes from the socket.
Definition socket.cpp:187
mx_socket_fd sockfd() const
Return the underlying socket handle.
Definition socket.cpp:183
Socket & operator=(const Socket &s)=delete
bool connect_unix(const std::string_view path)
Connect to a UNIX-domain endpoint.
Definition socket.cpp:92
bool connect(const std::string_view host, const std::string_view port)
Connect to a remote Internet endpoint.
Definition socket.cpp:80
ssize_t recvfrom(void *buf, size_t bytes)
Receive a datagram using the configured socket type.
Definition socket.cpp:216
ssize_t mx_socket_read(MXSocket *s, void *data, size_t len, int flags)
Read data from a socket.
Definition mxsocket.c:422
bool mx_socket_ipv6_connect(MXSocket *s, const char *host, const char *port, int type)
Connect an IPv6 Internet socket to a remote host.
Definition mxsocket.c:366
ssize_t mx_socket_recvfrom_address(MXSocket *sock, void *buf, size_t bytes, MXSocketAddress *address)
Definition mxsocket.c:614
int mx_socket_fd
Definition mxsocket.h:48
#define SOCK_ESHUTDOWN
Definition mxsocket.h:59
bool mx_socket_unix_bind(MXSocket *s, const char *path)
Bind a UNIX-domain socket to a local path.
Definition mxsocket.c:378
ssize_t mx_socket_read_all(MXSocket *sock, void *buf, size_t bytes)
Read the requested number of bytes from a socket.
Definition mxsocket.c:555
void mx_socket_close(MXSocket *s)
Close a socket if it is open.
Definition mxsocket.c:323
#define mx_close_socket(s)
Definition mxsocket.h:49
ssize_t mx_socket_recvfrom(MXSocket *sock, void *buf, size_t bytes)
Receive a datagram using an Internet socket.
Definition mxsocket.c:601
#define SOCK_ERRNO
Definition mxsocket.h:51
#define SOCK_ECONNRESET
Definition mxsocket.h:60
bool mx_socket_is_open(const MXSocket *s)
Check whether the socket is open.
Definition mxsocket.c:442
bool mx_socket_set_blocking(MXSocket *s, bool state)
Toggle blocking mode for a socket.
Definition mxsocket.c:331
ssize_t mx_socket_sendto_address(MXSocket *sock, const void *buf, size_t bytes, const MXSocketAddress *address)
Definition mxsocket.c:625
#define SOCK_EINVAL
Definition mxsocket.h:56
#define SOCK_ECONNABORTED
Definition mxsocket.h:55
ssize_t mx_socket_write_all(MXSocket *sock, const void *buf, size_t bytes)
Write the requested number of bytes to a socket.
Definition mxsocket.c:535
bool mx_socket_unix_connect(MXSocket *s, const char *path, int type)
Connect a UNIX-domain socket to a local path.
Definition mxsocket.c:241
bool mx_socket_valid(const MXSocket *s)
Check whether the socket handle is valid.
Definition mxsocket.c:416
#define SOCK_EBADF
Definition mxsocket.h:57
#define SOCK_EWOULDBLOCK
Definition mxsocket.h:54
bool mx_socket_unix_listen(MXSocket *s, const char *path, int backlog, int type)
Create and bind a UNIX-domain socket for listening.
Definition mxsocket.c:202
ssize_t mx_socket_unix_sendto(MXSocket *sock, const void *buf, size_t bytes)
Send a datagram using a UNIX-domain socket.
Definition mxsocket.c:645
#define SOCK_EAGAIN
Definition mxsocket.h:53
bool mx_socket_listen(MXSocket *s, const char *port, int backlog, int type)
Create and bind an Internet socket for listening.
Definition mxsocket.c:270
bool mx_socket_accept(const MXSocket *input, MXSocket *output)
Accept an incoming connection.
Definition mxsocket.c:278
ssize_t mx_socket_send(MXSocket *s, const void *data, size_t len, int flags)
Write data to a socket.
Definition mxsocket.c:432
bool mx_socket_connect(MXSocket *s, const char *host, const char *port, int type)
Connect an Internet socket to a remote host.
Definition mxsocket.c:362
#define NULL_SOCKET
Definition mxsocket.h:62
ssize_t mx_socket_ipv6_recvfrom(MXSocket *sock, void *buf, size_t bytes)
Receive a datagram using an IPv6 Internet socket.
Definition mxsocket.c:632
bool mx_socket_ipv6_bind(MXSocket *s, const char *port)
Bind an IPv6 Internet socket to a local port.
Definition mxsocket.c:374
bool mx_socket_readline(MXSocket *s, char **buffer, size_t *len)
Read a line of text from a socket.
Definition mxsocket.c:474
bool mx_socket_ipv6_listen(MXSocket *s, const char *port, int backlog, int type)
Create and bind an IPv6 Internet socket for listening.
Definition mxsocket.c:274
#define SOCK_ENOTSOCK
Definition mxsocket.h:58
bool mx_socket_bind(MXSocket *s, const char *port)
Bind an Internet socket to a local port.
Definition mxsocket.c:370
ssize_t mx_socket_sendto(MXSocket *sock, const void *buf, size_t bytes)
Send a datagram using an Internet socket.
Definition mxsocket.c:583
bool mx_socket_init(MXSocket *s)
Initialize a socket structure with default values.
Definition mxsocket.c:407
ssize_t mx_socket_ipv6_sendto(MXSocket *sock, const void *buf, size_t bytes)
Send a datagram using an IPv6 Internet socket.
Definition mxsocket.c:592
#define SOCK_EINTR
Definition mxsocket.h:52
ssize_t mx_socket_unix_recvfrom(MXSocket *sock, void *buf, size_t bytes)
Receive a datagram using a UNIX-domain socket.
Definition mxsocket.c:653
SocketType
Socket family and transport type.
Definition socket.hpp:37
@ TYPE_INVALID
No socket type selected.
Definition socket.hpp:39
@ TYPE_UNIX_DGRAM
UNIX-domain datagram socket.
Definition socket.hpp:51
@ TYPE_INET_DGRAM
IPv4 datagram socket.
Definition socket.hpp:47
@ TYPE_INET6_DGRAM
IPv6 datagram socket.
Definition socket.hpp:49
@ TYPE_UNIX
UNIX-domain stream socket.
Definition socket.hpp:45
@ TYPE_INET6
IPv6 stream socket.
Definition socket.hpp:43
@ TYPE_INET
IPv4 stream socket.
Definition socket.hpp:41
socklen_t length
Definition mxsocket.h:79
struct sockaddr_storage storage
Definition mxsocket.h:78
Cross-platform socket state used by the C API.
Definition mxsocket.h:68
struct sockaddr_in6 inet6
IPv6 address storage.
Definition mxsocket.h:74
bool blocking
True when the socket is in blocking mode.
Definition mxsocket.h:71
struct sockaddr_in inet
IPv4 address storage.
Definition mxsocket.h:73
struct sockaddr_un sun
UNIX-domain address storage.
Definition mxsocket.h:72
mx_socket_fd sockfd
Underlying socket handle.
Definition mxsocket.h:69
socklen_t addrlen
Length of the active address structure.
Definition mxsocket.h:70
MXNetworkInit()
Initialize the socket backend for the current process.
Definition socket.cpp:14
~MXNetworkInit()
Shut down the socket backend.
Definition socket.cpp:25
MXSocketAddress value
Definition socket.hpp:13
bool operator==(const SocketAddress &other) const
Definition socket.cpp:9