Jpp  15.0.1-rc.2-highQE
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 #include "JSystem/JNetwork.hh"
15 #include "JNet/JSocketAddress.hh"
16 
17 
18 #define IPROTO_TCP 6
19 
20 
21 /**
22  * \author mdejong
23  */
24 
25 /**
26  * Interprocess communication.
27  */
28 namespace JNET {}
29 namespace JPP { using namespace JNET; }
30 
31 namespace JNET {
32 
33  using JLANG::JFile;
38 
39 
40  /**
41  * Socket class.
42  */
43  class JSocket :
44  public JFile,
45  public JSocketAddress
46  {
47  public:
48  /**
49  * Default constructor.
50  */
51  JSocket() :
52  JFile()
53  {}
54 
55 
56  /**
57  * Constructor.
58  *
59  * \param type socket type
60  */
61  JSocket(const int type) :
62  JFile(socket(PF_INET, type, 0))
63  {
64  if (getFileDescriptor() < 0) {
65  THROW(JSocketException, "Error opening socket.");
66  }
67 
68  setFamily(AF_INET);
69  }
70 
71 
72  /**
73  * Constructor.
74  *
75  * \param domain communication domain
76  * \param type socket type
77  * \param protocol protocol
78  */
79  JSocket(const int domain,
80  const int type,
81  const int protocol = 0) :
82  JFile(socket(domain, type, protocol))
83  {
84  if (getFileDescriptor() < 0) {
85  THROW(JSocketException, "Error opening socket.");
86  }
87 
88  setFamily(domain);
89  }
90 
91 
92  /**
93  * Shut down socket.
94  */
95  int shutdown()
96  {
97  const int value = ::shutdown(getFileDescriptor(), SHUT_RDWR);
98 
99  close();
100 
101  return value;
102  }
103 
104 
105  /**
106  * Set non-blocking of I/O.
107  *
108  * \param on true to enable non-blocking; false to disable
109  */
110  void setNonBlocking(const bool on)
111  {
112  const int flags = fcntl(getFileDescriptor(), F_GETFL, -1);
113  const int mask = FNDELAY;
114 
115  if (flags == -1) {
116  THROW(JSocketException, "Get socket option failed.");
117  }
118 
119  if (((flags & mask) != mask && on) ||
120  ((flags & mask) != 0 && !on) ) {
121 
122  if (fcntl(getFileDescriptor(), F_SETFL, flags ^ mask) < 0) {
123  THROW(JSocketException, "Set socket option failed.");
124  }
125  }
126  }
127 
128 
129  /**
130  * Get non-blocking of I/O.
131  *
132  * \return true if enabled non-blocking; else false
133  */
134  bool getNonBlocking() const
135  {
136  const int flags = fcntl(getFileDescriptor(), F_GETFL, -1);
137  const int mask = FNDELAY;
138 
139  if (flags == -1) {
140  THROW(JSocketException, "Get socket option failed.");
141  }
142 
143  return ((flags & mask) != 0);
144  }
145 
146 
147  /**
148  * Set keep alive of socket.
149  *
150  * \param on true to enable keep alive; false to disable
151  */
152  void setKeepAlive(const bool on)
153  {
154  setOption(SOL_SOCKET, SO_KEEPALIVE, int(on ? 1 : 0));
155  }
156 
157 
158  /**
159  * Get keep alive of socket.
160  *
161  * \return true if keep alive; else false
162  */
163  bool getKeepAlive() const
164  {
165  return (getOption<int>(SOL_SOCKET, SO_KEEPALIVE) == 1);
166  }
167 
168 
169  /**
170  * Set the TCP idle time.
171  *
172  * \param t_s time [s]
173  */
174  void setKeepIdle(const int t_s)
175  {
176  setOption(IPROTO_TCP, TCP_KEEPIDLE, t_s);
177  }
178 
179 
180  /**
181  * Set the TCP idle count.
182  *
183  * \param count count
184  */
185  void setKeepCnt(const int count)
186  {
187  setOption(IPROTO_TCP, TCP_KEEPCNT, count);
188  }
189 
190 
191  /**
192  * Set the TCP interval time.
193  *
194  * \param t_s time [s]
195  */
196  void setKeepIntvl(const int t_s)
197  {
198  setOption(IPROTO_TCP, TCP_KEEPINTVL, t_s);
199  }
200 
201 
202  /**
203  * Set reuse address.
204  *
205  * \param on true to enable reuse address; false to disable
206  */
207  void setReuseAddress(const bool on)
208  {
209  setOption(SOL_SOCKET, SO_REUSEADDR, int(on ? 1 : 0));
210  }
211 
212 
213  /**
214  * Get reuse address.
215  *
216  * \return true if enable reuse address; else false
217  */
218  bool getReuseAddress() const
219  {
220  return (getOption<int>(SOL_SOCKET, SO_REUSEADDR) == 1);
221  }
222 
223 
224  /**
225  * Set TCP no-delay.
226  *
227  * \param on true to set TCP no-delay; false to disable
228  */
229  void setTcpNoDelay(const bool on)
230  {
231  setOption(IPPROTO_TCP, TCP_NODELAY, int(on ? 1 : 0));
232  }
233 
234 
235  /**
236  * Get TCP no-delay.
237  *
238  * \return true if TCP no-delay; else false
239  */
240  bool getTcpNoDelay() const
241  {
242  return (getOption<int>(IPPROTO_TCP, TCP_NODELAY) == 1);
243  }
244 
245 
246  /**
247  * Set receive buffer size.
248  *
249  * \param size number of bytes
250  */
251  void setReceiveBufferSize(const int size)
252  {
253  setOption(SOL_SOCKET, SO_RCVBUF, int(size));
254  }
255 
256 
257  /**
258  * Set receive buffer size.
259  *
260  * \return number of bytes
261  */
263  {
264  return getOption<int>(SOL_SOCKET, SO_RCVBUF);
265  }
266 
267 
268  /**
269  * Set send buffer size.
270  *
271  * \param size number of bytes
272  */
273  void setSendBufferSize(const int size)
274  {
275  setOption(SOL_SOCKET, SO_SNDBUF, int(size));
276  }
277 
278 
279  /**
280  * Get send buffer size.
281  *
282  * \return number of bytes
283  */
284  int getSendBufferSize() const
285  {
286  return getOption<int>(SOL_SOCKET, SO_SNDBUF);
287  }
288 
289 
290  /**
291  * Read data from socket.
292  *
293  * This method handles I/O errors in such a way that:
294  * -# the return value is set to zero if no data are read;
295  * -# an exception is thrown in case of a fatal error;
296  *
297  * \param buffer buffer
298  * \param length number of bytes to read
299  * \return number of bytes actually read
300  */
301  virtual int read(char* buffer, const int length) override
302  {
303  int pos = JFile::read(buffer, length);
304 
305  if (pos == 0) {
306 
307  THROW(JSocketException, "Socket read failed.");
308 
309  } else if (pos < 0) {
310 
311  switch (errno) {
312 
313  case EINTR:
314  case EWOULDBLOCK:
315  //case EAGAIN:
316  break;
317 
318  default:
319  THROW(JSocketException, "Socket read error.");
320  }
321 
322  pos = 0;
323  }
324 
325  return pos;
326  }
327 
328 
329  /**
330  * Write data to socket.
331  *
332  * This method handles I/O errors in such a way that:
333  * -# the return value is set to zero if no data are written;
334  * -# an exception is thrown in case of a fatal error;
335  *
336  * \param buffer buffer
337  * \param length number of bytes to write
338  * \return number of bytes actually written
339  */
340  virtual int write(const char* buffer, const int length) override
341  {
342  int pos = JFile::write(buffer, length);
343 
344  if (pos == 0) {
345 
346  THROW(JSocketException, "Socket write failed.");
347 
348  } else if (pos < 0) {
349 
350  switch (errno) {
351 
352  case EINTR:
353  case EWOULDBLOCK:
354  //case EAGAIN:
355  break;
356 
357  default:
358  THROW(JSocketException, "Socket write error.");
359  }
360 
361  pos = 0;
362  }
363 
364  return pos;
365  }
366 
367 
368  /**
369  * Accept connection from a server.
370  *
371  * \param server file descriptor of server socket
372  */
373  void accept(const int server)
374  {
375  socklen_t size = sizeof(sockaddr_in);
376  fileDescriptor = ::accept(server, getSockaddr(), &size);
377  }
378 
379 
380  /**
381  * Connect to port on local host.
382  *
383  * \param port port number
384  */
385  void connect(const int port)
386  {
387  connect(INADDR_ANY, port);
388  }
389 
390 
391  /**
392  * Connect to port on specified host.
393  *
394  * \param host_name host name
395  * \param port port number
396  */
397  void connect(const std::string& host_name, const int port)
398  {
399  connect(JSYSTEM::getIPnumber(host_name), port);
400  }
401 
402 
403  /**
404  * Connect to port on specified host.
405  *
406  * \param ip_number IP number
407  * \param port port number
408  */
409  void connect(const int ip_number, const int port)
410  {
411  setIPnumber(ip_number);
412  setPort(port);
413 
414  if (::connect(getFileDescriptor(), getSockaddr(), sizeof(sockaddr_in)) < 0) {
415  THROW(JSocketException, "Socket connection failed " << getIPaddress(ip_number) << ":" << port);
416  }
417  }
418 
419 
420  protected:
421  /**
422  * Set socket option.
423  *
424  * \param level level
425  * \param option option
426  * \param value value
427  */
428  template<class T>
429  void setOption(const int level, const int option, const T value)
430  {
431  socklen_t size = sizeof(T);
432 
433  if (setsockopt(getFileDescriptor(), level, option, &value, size) < 0) {
434  THROW(JSocketException, "Set socket option failed.");
435  }
436  }
437 
438 
439  /**
440  * Get socket option.
441  *
442  * \param level level
443  * \param option option
444  * \return value
445  */
446  template<class T>
447  T getOption(const int level, const int option) const
448  {
449  T value;
450  socklen_t size = sizeof(T);
451 
452  if (getsockopt(getFileDescriptor(), level, option, &value, &size) < 0) {
453  THROW(JSocketException, "Get socket option failed.");
454  }
455 
456  return value;
457  }
458  };
459 }
460 
461 #endif
void setReuseAddress(const bool on)
Set reuse address.
Definition: JSocket.hh:207
int getIPnumber(const std::string &host_name)
Get IP number.
Definition: JNetwork.hh:117
int getSendBufferSize() const
Get send buffer size.
Definition: JSocket.hh:284
Exceptions.
bool getReuseAddress() const
Get reuse address.
Definition: JSocket.hh:218
void close()
Close file.
Definition: JFile.hh:55
void setSendBufferSize(const int size)
Set send buffer size.
Definition: JSocket.hh:273
int getReceiveBufferSize() const
Set receive buffer size.
Definition: JSocket.hh:262
void setKeepIdle(const int t_s)
Set the TCP idle time.
Definition: JSocket.hh:174
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:670
bool getNonBlocking() const
Get non-blocking of I/O.
Definition: JSocket.hh:134
std::string getIPaddress(const int ip)
Get IP address (decimal-dot notation).
Definition: JNetwork.hh:154
Socket class.
Definition: JSocket.hh:43
virtual int read(char *buffer, const int length)
Read data from file.
Definition: JFile.hh:74
void setIPnumber()
Set any IP number.
const sockaddr * getSockaddr() const
Get sockaddr.
virtual int read(char *buffer, const int length) override
Read data from socket.
Definition: JSocket.hh:301
bool getKeepAlive() const
Get keep alive of socket.
Definition: JSocket.hh:163
The JFile class extends the JAbstractFile class.
Definition: JFile.hh:26
void connect(const int ip_number, const int port)
Connect to port on specified host.
Definition: JSocket.hh:409
int getFileDescriptor() const
Get file descriptor.
void accept(const int server)
Accept connection from a server.
Definition: JSocket.hh:373
void setKeepIntvl(const int t_s)
Set the TCP interval time.
Definition: JSocket.hh:196
int shutdown()
Shut down socket.
Definition: JSocket.hh:95
The JSocketAddress class encapsulates the sockaddr_in data structure.
void setKeepCnt(const int count)
Set the TCP idle count.
Definition: JSocket.hh:185
do set_variable OUTPUT_DIRECTORY $WORKDIR T
void setPort(const int port)
Set port number.
JSocket(const int type)
Constructor.
Definition: JSocket.hh:61
JSocket(const int domain, const int type, const int protocol=0)
Constructor.
Definition: JSocket.hh:79
void setReceiveBufferSize(const int size)
Set receive buffer size.
Definition: JSocket.hh:251
std::string getHostname()
Get host name.
Definition: JNetwork.hh:77
#define IPROTO_TCP
Definition: JSocket.hh:18
T getOption(const int level, const int option) const
Get socket option.
Definition: JSocket.hh:447
std::vector< int > count
Definition: JAlgorithm.hh:180
Exception for socket.
Definition: JException.hh:432
void connect(const int port)
Connect to port on local host.
Definition: JSocket.hh:385
void setNonBlocking(const bool on)
Set non-blocking of I/O.
Definition: JSocket.hh:110
bool getTcpNoDelay() const
Get TCP no-delay.
Definition: JSocket.hh:240
void setKeepAlive(const bool on)
Set keep alive of socket.
Definition: JSocket.hh:152
void setTcpNoDelay(const bool on)
Set TCP no-delay.
Definition: JSocket.hh:229
JSocket()
Default constructor.
Definition: JSocket.hh:51
void connect(const std::string &host_name, const int port)
Connect to port on specified host.
Definition: JSocket.hh:397
void setFamily(const int family)
Set family.
virtual int write(const char *buffer, const int length) override
Write data to socket.
Definition: JSocket.hh:340
void setOption(const int level, const int option, const T value)
Set socket option.
Definition: JSocket.hh:429
virtual int write(const char *buffer, const int length)
Write data to file.
Definition: JFile.hh:87
Hostname and IP address functions.