1+ // ***************************************************************************/
2+ // This software is released under the 2-Clause BSD license, included
3+ // below.
4+ //
5+ // Copyright (c) 2024, Aous Naman
6+ // Copyright (c) 2024, Kakadu Software Pty Ltd, Australia
7+ // Copyright (c) 2024, The University of New South Wales, Australia
8+ //
9+ // Redistribution and use in source and binary forms, with or without
10+ // modification, are permitted provided that the following conditions are
11+ // met:
12+ //
13+ // 1. Redistributions of source code must retain the above copyright
14+ // notice, this list of conditions and the following disclaimer.
15+ //
16+ // 2. Redistributions in binary form must reproduce the above copyright
17+ // notice, this list of conditions and the following disclaimer in the
18+ // documentation and/or other materials provided with the distribution.
19+ //
20+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21+ // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+ // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23+ // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+ // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+ // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26+ // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+ // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+ // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+ // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+ // ***************************************************************************/
32+ // This file is part of the OpenJPH software implementation.
33+ // File: ojph_socket.h
34+ // Author: Aous Naman
35+ // Date: 17 April 2024
36+ // ***************************************************************************/
37+
38+ #ifndef OJPH_SOCKET_H
39+ #define OJPH_SOCKET_H
40+
41+ #include < string>
42+ #include " ojph_arch.h"
43+
44+ #ifdef OJPH_OS_WINDOWS
45+ #include < winsock2.h>
46+ #include < WS2tcpip.h>
47+
48+ typedef SOCKET ojph_socket;
49+ #define OJPH_INVALID_SOCKET (INVALID_SOCKET)
50+ #define OJPH_EWOULDBLOCK (WSAEWOULDBLOCK)
51+ #else
52+ #include < sys/types.h>
53+ #include < sys/socket.h>
54+ #include < netinet/in.h>
55+ #include < arpa/inet.h>
56+ #include < netdb.h>
57+ #include < unistd.h>
58+ #include < errno.h>
59+ #include < fcntl.h>
60+
61+ typedef int ojph_socket;
62+ #define OJPH_INVALID_SOCKET (-1 )
63+ #define OJPH_EWOULDBLOCK (EWOULDBLOCK)
64+ #endif
65+
66+ namespace ojph
67+ {
68+ namespace net
69+ {
70+
71+ // /////////////////////////////////////////////////////////////////////////
72+ //
73+ //
74+ //
75+ //
76+ //
77+ // /////////////////////////////////////////////////////////////////////////
78+
79+ // ************************************************************************/
80+ /* * @brief A small wrapper for socket that only abstract Winsock2
81+ *
82+ * This is a small wrapper that only abstracts the difference between
83+ * Windows and Linux/MacOS socket implementations.
84+ * It does not not do much other than define a local member variable
85+ * of type int for Linux/OS and type SOCKET for Windows, which is
86+ * unsigned int/int64.
87+ */
88+ class socket {
89+ public:
90+ /* *
91+ * @brief default constructor
92+ */
93+ socket () { s = OJPH_INVALID_SOCKET; }
94+
95+ /* *
96+ * @brief a copy constructor
97+ */
98+ socket (const ojph_socket& s);
99+
100+ /* *
101+ * @brief Abstracts socket closing function
102+ */
103+ void close ();
104+
105+ /* *
106+ * @brief Sets the blocking mode
107+ *
108+ * @param block sets to true to operate in blocking mode
109+ * @return returns true when the operation succeeds
110+ */
111+ bool set_blocking_mode (bool block);
112+
113+ /* *
114+ * @brief provides access to the internal socket handle
115+ *
116+ * @return returns the internal socket handle
117+ */
118+ ojph_socket intern () { return s; }
119+
120+ private:
121+ ojph_socket s; // !<int for Linux/MacOS and SOCKET for Windows
122+ };
123+
124+ // /////////////////////////////////////////////////////////////////////////
125+ //
126+ //
127+ //
128+ //
129+ //
130+ // /////////////////////////////////////////////////////////////////////////
131+
132+ // ************************************************************************/
133+ /* * @brief A small wrapper for some Winsock2 functionality
134+ *
135+ * This is useful for windows, as it initializes and destroys
136+ * WinSock2 library.
137+ * It keeps a count of how many times the constructor is called,
138+ * reducing the count whenever the destructor is called. When the
139+ * count reaches zero, the library is destroyed -- Windows only.
140+ *
141+ * It also allows the creation of a socket, access to the last error
142+ * in a portable way, and the translation of an error into a text
143+ * message.
144+ */
145+ class socket_manager {
146+ public:
147+ /* *
148+ * @brief default constructor
149+ *
150+ * This function initializes the Winsock2 stack in windows; it
151+ * also increments the static member that keeps count of how many
152+ * times this object is used.
153+ */
154+ socket_manager ();
155+
156+ /* *
157+ * @brief default constructor
158+ *
159+ * This function cleans up the Winsock2 stack in windows when
160+ * the static member that keeps count of how many times this object
161+ * is used reaches zero.
162+ *
163+ */
164+ ~socket_manager ();
165+
166+ /* *
167+ * @brief Abstructs socket creation
168+ *
169+ * This function takes the same parameters as the conventional
170+ * socket() function
171+ *
172+ * @param domain the same as in conventional socket() function
173+ * @param type the same as in conventional socket() function
174+ * @param protocol the same as in conventional socket() function
175+ * @return returns an abstraction of socket
176+ *
177+ */
178+ socket create_socket (int domain, int type, int protocol);
179+
180+ /* *
181+ * @brief Abstructs get last error or errno
182+ *
183+ * This function abstracts Windows GetLastError or Linux errno
184+ *
185+ * @return returns a number representing the error
186+ *
187+ */
188+ int get_last_error ();
189+
190+ /* *
191+ * @brief Abstructs obtaining a textual message for an errnum
192+ *
193+ * This function abstracts obtaining a textual message for an errnum
194+ *
195+ * @param errnum the error number
196+ * @return a string holding a textual message for the error number
197+ *
198+ */
199+ std::string get_error_message (int errnum);
200+
201+ /* *
202+ * @brief Abstructs obtaining a textual message for GetLastError/errno
203+ *
204+ * This function combines get_error_message() and get_last_error().
205+ * This function effectively calls get_last_error() and uses the
206+ * returned error number to obtain a string by calling
207+ * get_error_message(errnum).
208+ *
209+ * @return a string holding a textual message for the error number
210+ *
211+ */
212+ std::string get_last_error_message ();
213+
214+ /* *
215+ * @brief Abstractly obtains the 32-bit IPv4 address integer
216+ *
217+ * This function obtains a 32-bit integer that represents the IPv4
218+ * address in abstrct way (working both in Windows and Linux).
219+ * This is really an independent function, but it is convenient to
220+ * put it here.
221+ *
222+ * @return returns an integer holding IPv4 address
223+ *
224+ */
225+ static ui32 get_addr (const sockaddr_in& addr);
226+
227+ private:
228+ static int ojph_socket_manager_counter;
229+ };
230+
231+ } // !net namespace
232+ } // !ojph namespace
233+
234+
235+
236+ #endif // !OJPH_SOCKET_H
0 commit comments