sptk2 logo
SPTK Home Page
BaseSocket.h
1/*
2╔══════════════════════════════════════════════════════════════════════════════╗
3║ SIMPLY POWERFUL TOOLKIT (SPTK) ║
4╟──────────────────────────────────────────────────────────────────────────────╢
5║ copyright © 1999-2022 Alexey Parshin. All rights reserved. ║
6║ email alexeyp@gmail.com ║
7╚══════════════════════════════════════════════════════════════════════════════╝
8┌──────────────────────────────────────────────────────────────────────────────┐
9│ This library is free software; you can redistribute it and/or modify it │
10│ under the terms of the GNU Library General Public License as published by │
11│ the Free Software Foundation; either version 2 of the License, or (at your │
12│ option) any later version. │
13│ │
14│ This library is distributed in the hope that it will be useful, but │
15│ WITHOUT ANY WARRANTY; without even the implied warranty of │
16│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library │
17│ General Public License for more details. │
18│ │
19│ You should have received a copy of the GNU Library General Public License │
20│ along with this library; if not, write to the Free Software Foundation, │
21│ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. │
22│ │
23│ Please report all bugs and problems to alexeyp@gmail.com. │
24└──────────────────────────────────────────────────────────────────────────────┘
25*/
26
27#pragma once
28
29#include <chrono>
30#include <sptk5/Buffer.h>
31#include <sptk5/DateTime.h>
32#include <sptk5/Exception.h>
33#include <sptk5/Strings.h>
34#include <sptk5/net/Host.h>
35
36#ifndef _WIN32
37
38#include <arpa/inet.h>
39#include <fcntl.h>
40#include <netdb.h>
41#include <netinet/in.h>
42#include <sys/ioctl.h>
43#include <sys/socket.h>
44#include <sys/time.h>
45#include <sys/types.h>
46#include <sys/un.h>
47#include <unistd.h>
48
52using SOCKET = int;
53using SOCKET_ADDRESS_FAMILY = sa_family_t;
54
55#ifdef __APPLE__
56using socklen_t = int;
57#endif
58
62#define INVALID_SOCKET (-1)
63
64#else
65#include <winsock2.h>
66#include <ws2tcpip.h>
67
68#include <windows.h>
69using socklen_t = int;
70using SOCKET_ADDRESS_FAMILY = unsigned short;
71#endif
72
73namespace sptk {
74
86class SP_EXPORT BaseSocket
87{
88public:
92 enum class OpenMode : uint8_t
93 {
94 CREATE,
95 CONNECT,
96 BIND
97 };
98
102 SOCKET fd() const
103 {
104 return m_sockfd;
105 }
106
113 void open_addr(OpenMode openMode = OpenMode::CREATE, const sockaddr_in* addr = nullptr,
114 std::chrono::milliseconds timeout = std::chrono::milliseconds(0));
115
122 explicit BaseSocket(SOCKET_ADDRESS_FAMILY domain = AF_INET, int32_t type = SOCK_STREAM, int32_t protocol = 0);
123
128 BaseSocket(const BaseSocket& other) = delete;
129
134 BaseSocket(BaseSocket&& other) noexcept = default;
135
139 virtual ~BaseSocket();
140
145 BaseSocket& operator=(const BaseSocket& other) = delete;
146
151 BaseSocket& operator=(BaseSocket&& other) noexcept = default;
152
157 void blockingMode(bool blocking);
158
162 [[nodiscard]] virtual size_t socketBytes();
163
168 virtual void attach(SOCKET socketHandle, bool accept);
169
175 virtual SOCKET detach();
176
181 void host(const Host& host);
182
186 [[nodiscard]] const Host& host() const
187 {
188 return m_host;
189 }
190
198 void open(const Host& host = Host(), OpenMode openMode = OpenMode::CONNECT, bool blockingMode = true,
199 std::chrono::milliseconds timeoutMS = std::chrono::milliseconds(0))
200 {
201 _open(host, openMode, blockingMode, timeoutMS);
202 }
203
211 void open(const struct sockaddr_in& address, OpenMode openMode = OpenMode::CONNECT,
212 bool blockingMode = true, std::chrono::milliseconds timeoutMS = std::chrono::milliseconds(0))
213 {
214 _open(address, openMode, blockingMode, timeoutMS);
215 }
216
222 void bind(const char* address, uint32_t portNumber);
223
228 void listen(uint16_t portNumber = 0);
229
233 virtual void close() noexcept;
234
239 [[nodiscard]] bool active() const
240 {
241 return m_sockfd != INVALID_SOCKET;
242 }
243
247 int32_t control(int flag, const uint32_t* check) const;
248
253 void setOption(int level, int option, int value) const;
254
260 void getOption(int level, int option, int& value) const;
261
268 [[nodiscard]] virtual size_t recv(uint8_t* buffer, size_t len);
269
276 [[nodiscard]] virtual size_t send(const uint8_t* buffer, size_t len);
277
285 [[nodiscard]] virtual size_t read(uint8_t* buffer, size_t size, sockaddr_in* from);
286
293 [[nodiscard]] virtual size_t read(uint8_t* buffer, size_t size)
294 {
295 return read(buffer, size, nullptr);
296 }
297
307 [[nodiscard]] virtual size_t read(Buffer& buffer, size_t size, sockaddr_in* from);
308
317 [[nodiscard]] size_t read(Buffer& buffer, size_t size)
318 {
319 return read(buffer, size, nullptr);
320 }
321
331 [[nodiscard]] virtual size_t read(String& buffer, size_t size, sockaddr_in* from);
332
341 [[nodiscard]] size_t read(String& buffer, size_t size)
342 {
343 return read(buffer, size, nullptr);
344 }
345
355 virtual size_t write(const uint8_t* buffer, size_t size, const sockaddr_in* peer);
356
365 size_t write(const uint8_t* buffer, size_t size)
366 {
367 return write(buffer, size, nullptr);
368 }
369
376 virtual size_t write(const Buffer& buffer, const sockaddr_in* peer);
377
383 size_t write(const Buffer& buffer)
384 {
385 return write(buffer, nullptr);
386 }
387
394 virtual size_t write(const String& buffer, const sockaddr_in* peer);
395
401 size_t write(const String& buffer)
402 {
403 return write(buffer, nullptr);
404 }
405
410 [[nodiscard]] virtual bool readyToRead(std::chrono::milliseconds timeout);
411
416 [[nodiscard]] virtual bool readyToWrite(std::chrono::milliseconds timeout);
417
422 [[nodiscard]] bool blockingMode() const
423 {
424 return m_blockingMode;
425 }
426
427protected:
431 void setSocketFD(SOCKET socket)
432 {
433 m_sockfd = socket;
434 }
435
439 [[nodiscard]] int32_t domain() const
440 {
441 return m_domain;
442 }
443
447 [[nodiscard]] int32_t type() const
448 {
449 return m_type;
450 }
451
455 [[nodiscard]] int32_t protocol() const
456 {
457 return m_protocol;
458 }
459
460#ifdef _WIN32
464 static void init() noexcept;
465
469 static void cleanup() noexcept;
470#endif
471
479 virtual void _open(const Host& host, OpenMode openMode, bool blockingMode, std::chrono::milliseconds timeoutMS);
480
488 virtual void _open(const struct sockaddr_in& address, OpenMode openMode, bool blockingMode,
489 std::chrono::milliseconds timeoutMS)
490 {
491 // Implement in derived class
492 }
493
494private:
495 SOCKET m_sockfd {INVALID_SOCKET};
496 int32_t m_domain;
497 int32_t m_type;
498 int32_t m_protocol;
499 Host m_host;
500 bool m_blockingMode {false};
501};
502
509SP_EXPORT void throwSocketError(const String& message, const char* file, int line);
510
511#define THROW_SOCKET_ERROR(msg) sptk::throwSocketError(msg, __FILE__, __LINE__)
512
516} // namespace sptk
Definition: BaseSocket.h:87
virtual ~BaseSocket()
Destructor.
void open_addr(OpenMode openMode=OpenMode::CREATE, const sockaddr_in *addr=nullptr, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
bool blockingMode() const
Return current blocking mode state.
Definition: BaseSocket.h:422
void listen(uint16_t portNumber=0)
void getOption(int level, int option, int &value) const
virtual size_t read(uint8_t *buffer, size_t size, sockaddr_in *from)
size_t write(const String &buffer)
Definition: BaseSocket.h:401
size_t read(String &buffer, size_t size)
Definition: BaseSocket.h:341
size_t write(const uint8_t *buffer, size_t size)
Definition: BaseSocket.h:365
virtual size_t recv(uint8_t *buffer, size_t len)
virtual size_t read(String &buffer, size_t size, sockaddr_in *from)
int32_t domain() const
Definition: BaseSocket.h:439
void bind(const char *address, uint32_t portNumber)
BaseSocket(SOCKET_ADDRESS_FAMILY domain=AF_INET, int32_t type=SOCK_STREAM, int32_t protocol=0)
const Host & host() const
Definition: BaseSocket.h:186
virtual void _open(const Host &host, OpenMode openMode, bool blockingMode, std::chrono::milliseconds timeoutMS)
int32_t control(int flag, const uint32_t *check) const
virtual size_t write(const String &buffer, const sockaddr_in *peer)
BaseSocket(const BaseSocket &other)=delete
virtual size_t write(const Buffer &buffer, const sockaddr_in *peer)
BaseSocket & operator=(const BaseSocket &other)=delete
virtual void _open(const struct sockaddr_in &address, OpenMode openMode, bool blockingMode, std::chrono::milliseconds timeoutMS)
Definition: BaseSocket.h:488
virtual bool readyToWrite(std::chrono::milliseconds timeout)
void blockingMode(bool blocking)
OpenMode
Definition: BaseSocket.h:93
size_t read(Buffer &buffer, size_t size)
Definition: BaseSocket.h:317
BaseSocket(BaseSocket &&other) noexcept=default
virtual size_t socketBytes()
virtual SOCKET detach()
virtual bool readyToRead(std::chrono::milliseconds timeout)
void setSocketFD(SOCKET socket)
Definition: BaseSocket.h:431
void open(const struct sockaddr_in &address, OpenMode openMode=OpenMode::CONNECT, bool blockingMode=true, std::chrono::milliseconds timeoutMS=std::chrono::milliseconds(0))
Definition: BaseSocket.h:211
virtual size_t write(const uint8_t *buffer, size_t size, const sockaddr_in *peer)
virtual void attach(SOCKET socketHandle, bool accept)
void host(const Host &host)
size_t write(const Buffer &buffer)
Definition: BaseSocket.h:383
virtual size_t read(Buffer &buffer, size_t size, sockaddr_in *from)
virtual size_t read(uint8_t *buffer, size_t size)
Definition: BaseSocket.h:293
void setOption(int level, int option, int value) const
SOCKET fd() const
Definition: BaseSocket.h:102
virtual size_t send(const uint8_t *buffer, size_t len)
int32_t protocol() const
Definition: BaseSocket.h:455
BaseSocket & operator=(BaseSocket &&other) noexcept=default
int32_t type() const
Definition: BaseSocket.h:447
void open(const Host &host=Host(), OpenMode openMode=OpenMode::CONNECT, bool blockingMode=true, std::chrono::milliseconds timeoutMS=std::chrono::milliseconds(0))
Definition: BaseSocket.h:198
virtual void close() noexcept
Definition: Buffer.h:51
Definition: Host.h:55
Definition: String.h:49
SP_EXPORT void throwSocketError(const String &message, const char *file, int line)

Fri Oct 14 2022 09:58:32: SPTK 5.4.1