Jpp  19.1.0
the software that should make you happy
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 
17 #include "JNet/JSocketAddress.hh"
18 
19 
20 /**
21  * \file
22  * Base class for interprocess communication.
23  *
24  * \author mdejong
25  */
26 namespace JNET {}
27 namespace JPP { using namespace JNET; }
28 
29 namespace 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  */
46  JSocket() :
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  */
89  int shutdown()
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  */
181  int getSendBufferSize() const
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.
Definition: JException.hh:712
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.
Definition: JException.hh:468
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).