ccuty  1.0
 All Classes Namespaces Files Functions Enumerations Macros Pages
ccsocket.hpp
Go to the documentation of this file.
1 //
2 // cpsocket: C++ Classes for TCP/IP and UDP Datagram INET Sockets.
3 // (c) Eric Lecolinet 2016/17 - https://www.telecom-paristech.fr/~elc
4 //
5 
15 #ifndef ccuty_ccsocket
16 #define ccuty_ccsocket
17 
19 #include <string>
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 
24 namespace ccuty {
25 
26 // ignore SIGPIPES when possible
27 #if defined(MSG_NOSIGNAL)
28 # define _NO_SIGPIPE(flags) (flags | MSG_NOSIGNAL)
29 #else
30 # define _NO_SIGPIPE(flags) (flags)
31 #endif
32 
42  class Socket {
43  public:
49  enum Errors {Failed = -1, InvalidSocket = -2, UnknownHost = -3};
50 
57  Socket(int type = SOCK_STREAM);
58 
60  Socket(int type, int sockfd);
61 
63  virtual ~Socket();
64 
69  virtual int bind(int port);
70 
75  virtual int bind(const std::string& host, int port);
76 
82  virtual int connect(const std::string& host, int port);
83 
87  virtual int close();
88 
90  bool isClosed() const {return _sockfd < 0;}
91 
93  int descriptor() {return _sockfd;}
94 
103  ssize_t send(const void* buf, size_t len, int flags = 0) {
104  return ::send(_sockfd, buf, len, _NO_SIGPIPE(flags));
105  }
106 
116  ssize_t receive(void* buf, size_t len, int flags = 0) {
117  return ::recv(_sockfd, buf, len, flags);
118  }
119 
124  ssize_t sendTo(const void* buf, size_t len, int flags,
125  const struct sockaddr* dest_addr, socklen_t addrlen) {
126  return ::sendto(_sockfd, buf, len, _NO_SIGPIPE(flags), dest_addr, addrlen);
127  }
128 
134  ssize_t receiveFrom(void* buf, size_t len, int flags,
135  struct sockaddr* src_addr, socklen_t* addrlen) {
136  return ::recvfrom(_sockfd, buf, len, flags, src_addr, addrlen);
137  }
138 
140  virtual void shutdownInput();
141 
143  virtual void shutdownOutput();
144 
146  int setReceiveBufferSize(int size);
147 
149  int setReuseAddress(bool);
150 
152  int setSendBufferSize(int size);
153 
155  int setSoLinger(bool, int linger);
156 
158  int setSoTimeout(int timeout);
159 
161  int setTcpNoDelay(bool);
162 
164  int getReceiveBufferSize() const;
165 
167  bool getReuseAddress() const;
168 
170  int getSendBufferSize() const;
171 
173  bool getSoLinger(int& linger) const;
174 
176  int getSoTimeout() const;
177 
179  bool getTcpNoDelay() const;
180 
182  virtual int setLocalAddress(struct sockaddr_in& addr, int port);
183 
185  virtual int setAddress(struct sockaddr_in& addr, const std::string& host, int port);
186 
187  private:
188  friend class ServerSocket;
189  int _sockfd;
190  Socket(const Socket&) = delete;
191  Socket& operator=(const Socket&) = delete;
192  Socket& operator=(Socket&&) = delete;
193  };
194 
195  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
196 
202  class ServerSocket {
203  public:
207  ServerSocket();
208 
209  virtual ~ServerSocket();
210 
215  virtual Socket* accept();
216 
221  virtual int bind(int port, int backlog = 50);
222 
224  virtual int close();
225 
227  bool isClosed() const {return _sockfd < 0;}
228 
230  int descriptor() {return _sockfd;}
231 
233  int setReceiveBufferSize(int size);
234 
236  int setReuseAddress(bool);
237 
239  int setSoTimeout(int timeout);
240 
242  int setTcpNoDelay(bool);
243 
244  protected:
245  virtual Socket* createSocket(int sockfd);
246 
247  private:
248  int _sockfd; // listening socket.
249  ServerSocket(const ServerSocket&) = delete;
250  ServerSocket& operator=(const ServerSocket&) = delete;
251  ServerSocket& operator=(ServerSocket&&) = delete;
252  };
253 
254  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
255 
304  class SocketBuffer {
305  public:
313  SocketBuffer(Socket* socket, size_t inputBufferSize = 8192, size_t ouputBufferSize = 8192);
314  SocketBuffer(Socket& socket, size_t inputBufferSize = 8192, size_t ouputBufferSize = 8192);
315 
316  virtual ~SocketBuffer();
317 
335  virtual ssize_t readLine(std::string& message);
336 
356  virtual ssize_t writeLine(const std::string& message);
357 
358  /* Receives a given number of characters from a connected socket.
359  * Reads *exactly* _len_ bytes from the socket, blocks otherwise.
360  *
361  * @return the number of bytes that were received or:
362  * - 0: shutdownOutput() was called on the other side
363  * - Socket::Failed (-1): a connection error occured
364  * - Socket::InvalidSocket (-2): the socket is invalid.
365  */
366  virtual ssize_t read(char* buffer, size_t len);
367 
368  /* @brief Sends a given number of characters to a connected socket.
369  * Writes _len_ bytes to the socket.
370  *
371  * @return the number of bytes that were sent or:
372  * - 0: shutdownInput() was called on the other side
373  * - Socket::Failed (-1): a connection error occured
374  * - Socket::InvalidSocket (-2): the socket is invalid.
375  */
376  virtual ssize_t write(const char* str, size_t len);
377 
379  Socket* socket() {return _sock;}
380 
382  int readSeparator() const {return _inSep;}
383 
385  int writeSeparator() const {return _outSep;}
386 
395  virtual void setReadSeparator(int separ);
396 
405  virtual void setWriteSeparator(int separ);
406 
407  private:
408  SocketBuffer(const SocketBuffer&) = delete;
409  SocketBuffer& operator=(const SocketBuffer&) = delete;
410  SocketBuffer& operator=(SocketBuffer&&) = delete;
411 
412  protected:
413  virtual bool retrieveLine(std::string& str, ssize_t received);
414  size_t _inSize, _outSize;
415  int _inSep, _outSep;
416  Socket* _sock;
417  struct InputBuffer* _in;
418  };
419 
420 }
421 
422 #endif