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