10Duke Enterprise C++ SDK
Loading...
Searching...
No Matches
AbstractBaseSocket.h
1#ifndef TENDUKE_OSA_SOCKETTEMPLATE_H
2#define TENDUKE_OSA_SOCKETTEMPLATE_H
3
4#include "net/NetworkingException.h"
5#include "osa/Socket.h"
6
7#include <cstdint>
8#include <memory>
9#include <string>
10
11#if defined(__APPLE__) || defined(__linux__) || defined(__unix__) || defined(_POSIX_VERSION) || defined(__ANDROID__)
12
13#include <arpa/inet.h>
14#include <sys/socket.h>
15#include <sys/time.h>
16
17#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined (_WIN64)
18
19#include <WinSock2.h>
20
21#endif // OS-detection
22
23
24namespace tenduke { namespace osa {
25
29template<typename DESCRIPTOR_TYPE> class AbstractBaseSocket : public virtual ::tenduke::osa::Socket
30{
31public:
32 // Prevent copy construction
33 AbstractBaseSocket(const AbstractBaseSocket&) = delete;
34 AbstractBaseSocket& operator=(const AbstractBaseSocket&) = delete;
35
39 explicit AbstractBaseSocket(const DESCRIPTOR_TYPE descriptor)
41 {
42 }
43
47 std::unique_ptr<::tenduke::osa::Socket> accept(const uint32_t timeoutMs) override
48 {
49 if (hasIncomingConnections(timeoutMs)) {
50 return accept();
51 }
52 return nullptr;
53 }
54
56
60 void listen() override
61 {
62 const auto status = ::listen(descriptor, SOMAXCONN);
63 if (status != 0) {
64 throw ::tenduke::net::NetworkingException(mkErrorMessage("Error trying to listen() the socket: "));
65 }
66 }
67
71 int read(void * buffer, const std::size_t bufferSize) override
72 {
73 auto bytesRead = ::recv(
75 static_cast<char *>(buffer),
76 bufferSize,
77 0
78 );
79 // ::recv returns:
80 // >0 = number of bytes received
81 // 0 = socket closed gracefully
82 // <0 = error (Unix: errno, Windows: WSAGetLastError())
83 if (bytesRead < 0) {
84 const auto errorCode = getLastError();
85 if (wouldBlock(errorCode)) {
86 return -1;
87 }
88 throw ::tenduke::net::NetworkingException(mkErrorMessage("::recv() from socket failed: ", errorCode));
89 }
90 return static_cast<int>(bytesRead);
91 }
92
96 int write(const void * buffer, const std::size_t len) override
97 {
98 const auto bytesWritten = ::send(
100 static_cast<const char *>(buffer),
101 len,
102 0
103 );
104
105 if (bytesWritten < 0) {
106 throw ::tenduke::net::NetworkingException(mkErrorMessage("::send() to socket failed: "));
107 }
108
109 return static_cast<int>(bytesWritten);
110 }
111
112protected:
120 virtual bool hasIncomingConnections(std::uint32_t timeoutMs) const = 0;
121
126 virtual int getLastError() const = 0;
127
133 virtual std::string mkErrorMessage(const std::string &body)
134 const
135 {
136 return mkErrorMessage(body, getLastError());
137 }
138
144 virtual std::string mkErrorMessage(const char *body)
145 const
146 {
147 return mkErrorMessage(body, getLastError());
148 }
149
156 virtual std::string mkErrorMessage(const std::string &body, int errorCode) const = 0;
157
163 virtual bool wouldBlock(int errorCode) const = 0;
164
170 static struct ::timeval timeFromMilliseconds(const std::uint32_t milliseconds)
171 {
172 return {
173 static_cast<std::int32_t>(milliseconds) / 1000,
174 (static_cast<std::int32_t>(milliseconds) % 1000) * 1000 };
175 }
176
178 DESCRIPTOR_TYPE descriptor;
179};
180
181}}
182
183#endif //TENDUKE_OSA_SOCKETTEMPLATE_H
void listen() override
Configures the socket to listen for incoming connections.
Definition AbstractBaseSocket.h:60
AbstractBaseSocket(const DESCRIPTOR_TYPE descriptor)
Constructs a new socket.
Definition AbstractBaseSocket.h:39
int write(const void *buffer, const std::size_t len) override
Write bytes to the socket.number of bytes written
Definition AbstractBaseSocket.h:96
virtual std::string mkErrorMessage(const std::string &body) const
Builds error message.
Definition AbstractBaseSocket.h:133
virtual int getLastError() const =0
Returns last error code.
int read(void *buffer, const std::size_t bufferSize) override
Reads bytes from the socket.number of bytes read. Returns -1, if socket is non-blocking and nothing t...
Definition AbstractBaseSocket.h:71
virtual std::string mkErrorMessage(const char *body) const
Builds error message.
Definition AbstractBaseSocket.h:144
virtual std::string mkErrorMessage(const std::string &body, int errorCode) const =0
Builds error message.
virtual std::unique_ptr< Socket > accept()=0
Accepts next connection from listening socket.
virtual bool wouldBlock(int errorCode) const =0
Checks if error code means that call would have blocked.
static struct::timeval timeFromMilliseconds(const std::uint32_t milliseconds)
Returns struct timeval populated from milliseconds.
Definition AbstractBaseSocket.h:170
std::unique_ptr<::tenduke::osa::Socket > accept(const uint32_t timeoutMs) override
Accepts next connection from listening socket, with a timeout.The socket must be set to listening mod...
Definition AbstractBaseSocket.h:47
virtual bool hasIncomingConnections(std::uint32_t timeoutMs) const =0
Checks if the socket has incoming connections.
DESCRIPTOR_TYPE descriptor
The socket descriptor.
Definition AbstractBaseSocket.h:178
OS-independent abstraction of a socket.
Definition Socket.h:14
virtual std::unique_ptr< Socket > accept(uint32_t timeoutMs)=0
Accepts next connection from listening socket, with a timeout.
Operating system abstraction.
Definition win32_utils.h:7
Root for classes, functions and globals of 10Duke C++ Client.
Definition APIRequest.h:4