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