Jpp 19.3.0-rc.1
the software that should make you happy
Loading...
Searching...
No Matches
JSocket.hh
Go to the documentation of this file.
1#ifndef __JNET__JSOCKET__
2#define __JNET__JSOCKET__
3
4#include <sys/socket.h>
5#include <netdb.h>
6#include <netinet/tcp.h>
7#include <netinet/in.h>
8#include <fcntl.h>
9#include <errno.h>
10#include <string>
11
12#include "JLang/JException.hh"
13#include "JLang/JFile.hh"
14
15#include "JMath/JConstants.hh"
16
18
19
20/**
21 * \file
22 * Base class for interprocess communication.
23 *
24 * \author mdejong
25 */
26namespace JNET {}
27namespace JPP { using namespace JNET; }
28
29namespace JNET {
30
31 using JLANG::JFile;
33
34
35 /**
36 * Socket class.
37 */
38 class JSocket :
39 public JFile,
40 public JSocketAddress
41 {
42 public:
43 /**
44 * Default constructor.
45 */
47 JFile()
48 {}
49
50
51 /**
52 * Constructor.
53 *
54 * \param domain communication domain
55 * \param type socket type
56 * \param protocol protocol
57 */
58 JSocket(const int domain,
59 const int type,
60 const int protocol = 0) :
61 JFile(socket(domain, type, protocol))
62 {
63 if (getFileDescriptor() < 0) {
64 THROW(JSocketException, "Error opening socket " << errno);
65 }
66
67 setFamily(domain);
68 }
69
70 /**
71 * Default socket buffer size to be used on this system
72 *
73 * \return number of bytes
74 */
75 static const int getDefaultBufferSize()
76 {
77#if __APPLE__
78 return JMATH::MEGABYTE;
79#else
80 return JMATH::GIGABYTE;
81#endif
82 }
83
84 /**
85 * Shut down socket.
86 *
87 * \return return value
88 */
90 {
91 const int value = ::shutdown(getFileDescriptor(), SHUT_RDWR);
92
93 close();
94
95 return value;
96 }
97
98
99 /**
100 * Set keep alive of socket.
101 *
102 * \param on true to enable keep alive; false to disable
103 */
104 void setKeepAlive(const bool on)
105 {
106 setOption(SOL_SOCKET, SO_KEEPALIVE, int(on ? 1 : 0));
107 }
108
109
110 /**
111 * Get keep alive of socket.
112 *
113 * \return true if keep alive; else false
114 */
115 bool getKeepAlive() const
116 {
117 return (getOption<int>(SOL_SOCKET, SO_KEEPALIVE) == 1);
118 }
119
120
121 /**
122 * Set reuse address.
123 *
124 * \param on true to enable reuse address; false to disable
125 */
126 void setReuseAddress(const bool on)
127 {
128 setOption(SOL_SOCKET, SO_REUSEADDR, int(on ? 1 : 0));
129 }
130
131
132 /**
133 * Get reuse address.
134 *
135 * \return true if enable reuse address; else false
136 */
137 bool getReuseAddress() const
138 {
139 return (getOption<int>(SOL_SOCKET, SO_REUSEADDR) == 1);
140 }
141
142
143 /**
144 * Set receive buffer size.
145 *
146 * \param size number of bytes
147 */
148 void setReceiveBufferSize(const int size)
149 {
150 setOption(SOL_SOCKET, SO_RCVBUF, int(size));
151 }
152
153
154 /**
155 * Set receive buffer size.
156 *
157 * \return number of bytes
158 */
160 {
161 return getOption<int>(SOL_SOCKET, SO_RCVBUF);
162 }
163
164
165 /**
166 * Set send buffer size.
167 *
168 * \param size number of bytes
169 */
170 void setSendBufferSize(const int size)
171 {
172 setOption(SOL_SOCKET, SO_SNDBUF, int(size));
173 }
174
175
176 /**
177 * Get send buffer size.
178 *
179 * \return number of bytes
180 */
182 {
183 return getOption<int>(SOL_SOCKET, SO_SNDBUF);
184 }
185
186
187 /**
188 * Read data from socket.
189 *
190 * This method handles I/O errors in such a way that:
191 * -# the return value is set to zero if no data are read;
192 * -# an exception is thrown in case of a fatal error;
193 *
194 * \param buffer buffer
195 * \param length number of bytes to read
196 * \return number of bytes actually read
197 */
198 virtual int read(char* buffer, const int length) override
199 {
200 int pos = JFile::read(buffer, length);
201
202 if (pos == 0) {
203
204 THROW(JSocketException, "Socket read failed " << getFileDescriptor() << ' ' << errno);
205
206 } else if (pos < 0) {
207
208 switch (errno) {
209
210 case EINTR:
211 case EWOULDBLOCK:
212 //case EAGAIN:
213 break;
214
215 default:
216 THROW(JSocketException, "Socket read error " << getFileDescriptor() << ' ' << errno);
217 }
218
219 pos = 0;
220 }
221
222 return pos;
223 }
224
225
226 /**
227 * Write data to socket.
228 *
229 * This method handles I/O errors in such a way that:
230 * -# the return value is set to zero if no data are written;
231 * -# an exception is thrown in case of a fatal error;
232 *
233 * \param buffer buffer
234 * \param length number of bytes to write
235 * \return number of bytes actually written
236 */
237 virtual int write(const char* buffer, const int length) override
238 {
239 int pos = JFile::write(buffer, length);
240
241 if (pos == 0) {
242
243 THROW(JSocketException, "Socket write failed " << getFileDescriptor() << ' ' << errno);
244
245 } else if (pos < 0) {
246
247 switch (errno) {
248
249 case EINTR:
250 case EWOULDBLOCK:
251 //case EAGAIN:
252 break;
253
254 default:
255 THROW(JSocketException, "Socket write error " << getFileDescriptor() << ' ' << errno);
256 }
257
258 pos = 0;
259 }
260
261 return pos;
262 }
263
264
265 protected:
266 /**
267 * Set socket option.
268 *
269 * \param level level
270 * \param option option
271 * \param value value
272 */
273 template<class T>
274 void setOption(const int level, const int option, const T value)
275 {
276 socklen_t size = sizeof(T);
277
278 if (setsockopt(getFileDescriptor(), level, option, &value, size) < 0) {
279 THROW(JSocketException, "Set socket option failed " << errno);
280 }
281 }
282
283
284 /**
285 * Get socket option.
286 *
287 * \param level level
288 * \param option option
289 * \return value
290 */
291 template<class T>
292 T getOption(const int level, const int option) const
293 {
294 T value;
295 socklen_t size = sizeof(T);
296
297 if (getsockopt(getFileDescriptor(), level, option, &value, &size) < 0) {
298 THROW(JSocketException, "Get socket option failed " << errno);
299 }
300
301 return value;
302 }
303 };
304}
305
306#endif
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Mathematical constants.
int getFileDescriptor() const
Get file descriptor.
The JFile class extends the JAbstractFile class.
Definition JFile.hh:30
virtual int write(const char *buffer, const int length)
Write data to file.
Definition JFile.hh:93
virtual int read(char *buffer, const int length)
Read data from file.
Definition JFile.hh:80
int close()
Close file.
Definition JFile.hh:57
Exception for socket.
The JSocketAddress class encapsulates the sockaddr_in data structure.
void setFamily(const int family)
Set family.
Socket class.
Definition JSocket.hh:41
void setReceiveBufferSize(const int size)
Set receive buffer size.
Definition JSocket.hh:148
void setOption(const int level, const int option, const T value)
Set socket option.
Definition JSocket.hh:274
virtual int read(char *buffer, const int length) override
Read data from socket.
Definition JSocket.hh:198
T getOption(const int level, const int option) const
Get socket option.
Definition JSocket.hh:292
JSocket()
Default constructor.
Definition JSocket.hh:46
int getSendBufferSize() const
Get send buffer size.
Definition JSocket.hh:181
JSocket(const int domain, const int type, const int protocol=0)
Constructor.
Definition JSocket.hh:58
bool getKeepAlive() const
Get keep alive of socket.
Definition JSocket.hh:115
int getReceiveBufferSize() const
Set receive buffer size.
Definition JSocket.hh:159
static const int getDefaultBufferSize()
Default socket buffer size to be used on this system.
Definition JSocket.hh:75
int shutdown()
Shut down socket.
Definition JSocket.hh:89
bool getReuseAddress() const
Get reuse address.
Definition JSocket.hh:137
void setReuseAddress(const bool on)
Set reuse address.
Definition JSocket.hh:126
void setKeepAlive(const bool on)
Set keep alive of socket.
Definition JSocket.hh:104
void setSendBufferSize(const int size)
Set send buffer size.
Definition JSocket.hh:170
virtual int write(const char *buffer, const int length) override
Write data to socket.
Definition JSocket.hh:237
static const long long int GIGABYTE
Number of bytes in a mega-byte.
static const long long int MEGABYTE
Number of bytes in a kilo-byte.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).