Jpp  18.2.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  int shutdown()
73  {
74  const int value = ::shutdown(getFileDescriptor(), SHUT_RDWR);
75 
76  close();
77 
78  return value;
79  }
80 
81 
82  /**
83  * Set keep alive of socket.
84  *
85  * \param on true to enable keep alive; false to disable
86  */
87  void setKeepAlive(const bool on)
88  {
89  setOption(SOL_SOCKET, SO_KEEPALIVE, int(on ? 1 : 0));
90  }
91 
92 
93  /**
94  * Get keep alive of socket.
95  *
96  * \return true if keep alive; else false
97  */
98  bool getKeepAlive() const
99  {
100  return (getOption<int>(SOL_SOCKET, SO_KEEPALIVE) == 1);
101  }
102 
103 
104  /**
105  * Set reuse address.
106  *
107  * \param on true to enable reuse address; false to disable
108  */
109  void setReuseAddress(const bool on)
110  {
111  setOption(SOL_SOCKET, SO_REUSEADDR, int(on ? 1 : 0));
112  }
113 
114 
115  /**
116  * Get reuse address.
117  *
118  * \return true if enable reuse address; else false
119  */
120  bool getReuseAddress() const
121  {
122  return (getOption<int>(SOL_SOCKET, SO_REUSEADDR) == 1);
123  }
124 
125 
126  /**
127  * Set receive buffer size.
128  *
129  * \param size number of bytes
130  */
131  void setReceiveBufferSize(const int size)
132  {
133  setOption(SOL_SOCKET, SO_RCVBUF, int(size));
134  }
135 
136 
137  /**
138  * Set receive buffer size.
139  *
140  * \return number of bytes
141  */
143  {
144  return getOption<int>(SOL_SOCKET, SO_RCVBUF);
145  }
146 
147 
148  /**
149  * Set send buffer size.
150  *
151  * \param size number of bytes
152  */
153  void setSendBufferSize(const int size)
154  {
155  setOption(SOL_SOCKET, SO_SNDBUF, int(size));
156  }
157 
158 
159  /**
160  * Get send buffer size.
161  *
162  * \return number of bytes
163  */
164  int getSendBufferSize() const
165  {
166  return getOption<int>(SOL_SOCKET, SO_SNDBUF);
167  }
168 
169 
170  /**
171  * Read data from socket.
172  *
173  * This method handles I/O errors in such a way that:
174  * -# the return value is set to zero if no data are read;
175  * -# an exception is thrown in case of a fatal error;
176  *
177  * \param buffer buffer
178  * \param length number of bytes to read
179  * \return number of bytes actually read
180  */
181  virtual int read(char* buffer, const int length) override
182  {
183  int pos = JFile::read(buffer, length);
184 
185  if (pos == 0) {
186 
187  THROW(JSocketException, "Socket read failed " << errno);
188 
189  } else if (pos < 0) {
190 
191  switch (errno) {
192 
193  case EINTR:
194  case EWOULDBLOCK:
195  //case EAGAIN:
196  break;
197 
198  default:
199  THROW(JSocketException, "Socket read error " << errno);
200  }
201 
202  pos = 0;
203  }
204 
205  return pos;
206  }
207 
208 
209  /**
210  * Write data to socket.
211  *
212  * This method handles I/O errors in such a way that:
213  * -# the return value is set to zero if no data are written;
214  * -# an exception is thrown in case of a fatal error;
215  *
216  * \param buffer buffer
217  * \param length number of bytes to write
218  * \return number of bytes actually written
219  */
220  virtual int write(const char* buffer, const int length) override
221  {
222  int pos = JFile::write(buffer, length);
223 
224  if (pos == 0) {
225 
226  THROW(JSocketException, "Socket write failed " << errno);
227 
228  } else if (pos < 0) {
229 
230  switch (errno) {
231 
232  case EINTR:
233  case EWOULDBLOCK:
234  //case EAGAIN:
235  break;
236 
237  default:
238  THROW(JSocketException, "Socket write error " << errno);
239  }
240 
241  pos = 0;
242  }
243 
244  return pos;
245  }
246 
247 
248  protected:
249  /**
250  * Set socket option.
251  *
252  * \param level level
253  * \param option option
254  * \param value value
255  */
256  template<class T>
257  void setOption(const int level, const int option, const T value)
258  {
259  socklen_t size = sizeof(T);
260 
261  if (setsockopt(getFileDescriptor(), level, option, &value, size) < 0) {
262  THROW(JSocketException, "Set socket option failed " << errno);
263  }
264  }
265 
266 
267  /**
268  * Get socket option.
269  *
270  * \param level level
271  * \param option option
272  * \return value
273  */
274  template<class T>
275  T getOption(const int level, const int option) const
276  {
277  T value;
278  socklen_t size = sizeof(T);
279 
280  if (getsockopt(getFileDescriptor(), level, option, &value, &size) < 0) {
281  THROW(JSocketException, "Get socket option failed " << errno);
282  }
283 
284  return value;
285  }
286  };
287 }
288 
289 #endif
void setReuseAddress(const bool on)
Set reuse address.
Definition: JSocket.hh:109
int getSendBufferSize() const
Get send buffer size.
Definition: JSocket.hh:164
Exceptions.
bool getReuseAddress() const
Get reuse address.
Definition: JSocket.hh:120
void close()
Close file.
Definition: JFile.hh:55
void setSendBufferSize(const int size)
Set send buffer size.
Definition: JSocket.hh:153
int getReceiveBufferSize() const
Set receive buffer size.
Definition: JSocket.hh:142
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:712
Socket class.
Definition: JSocket.hh:36
virtual int read(char *buffer, const int length)
Read data from file.
Definition: JFile.hh:74
virtual int read(char *buffer, const int length) override
Read data from socket.
Definition: JSocket.hh:181
bool getKeepAlive() const
Get keep alive of socket.
Definition: JSocket.hh:98
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:72
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:131
T getOption(const int level, const int option) const
Get socket option.
Definition: JSocket.hh:275
Exception for socket.
Definition: JException.hh:466
void setKeepAlive(const bool on)
Set keep alive of socket.
Definition: JSocket.hh:87
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:220
void setOption(const int level, const int option, const T value)
Set socket option.
Definition: JSocket.hh:257
virtual int write(const char *buffer, const int length)
Write data to file.
Definition: JFile.hh:87