1//
2// Socket.h
3//
4// Library: Net
5// Package: Sockets
6// Module: Socket
7//
8// Definition of the Socket class.
9//
10// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Net_Socket_INCLUDED
18#define Net_Socket_INCLUDED
19
20
21#include "Poco/Net/Net.h"
22#include "Poco/Net/SocketImpl.h"
23#include <vector>
24
25
26namespace Poco {
27namespace Net {
28
29
30class Net_API Socket
31 /// Socket is the common base class for
32 /// StreamSocket, ServerSocket, DatagramSocket and other
33 /// socket classes.
34 ///
35 /// It provides operations common to all socket types.
36{
37public:
38 typedef SocketBufVec BufVec;
39
40 enum SelectMode
41 /// The mode argument to poll() and select().
42 {
43 SELECT_READ = 1,
44 SELECT_WRITE = 2,
45 SELECT_ERROR = 4
46 };
47
48 typedef std::vector<Socket> SocketList;
49
50 Socket();
51 /// Creates an uninitialized socket.
52
53 Socket(const Socket& socket);
54 /// Copy constructor.
55 ///
56 /// Attaches the SocketImpl from the other socket and
57 /// increments the reference count of the SocketImpl.
58
59 Socket& operator = (const Socket& socket);
60 /// Assignment operator.
61 ///
62 /// Releases the socket's SocketImpl and
63 /// attaches the SocketImpl from the other socket and
64 /// increments the reference count of the SocketImpl.
65
66 virtual ~Socket();
67 /// Destroys the Socket and releases the
68 /// SocketImpl.
69
70 bool operator == (const Socket& socket) const;
71 /// Returns true if both sockets share the same
72 /// SocketImpl, false otherwise.
73
74 bool operator != (const Socket& socket) const;
75 /// Returns false if both sockets share the same
76 /// SocketImpl, true otherwise.
77
78 bool operator < (const Socket& socket) const;
79 /// Compares the SocketImpl pointers.
80
81 bool operator <= (const Socket& socket) const;
82 /// Compares the SocketImpl pointers.
83
84 bool operator > (const Socket& socket) const;
85 /// Compares the SocketImpl pointers.
86
87 bool operator >= (const Socket& socket) const;
88 /// Compares the SocketImpl pointers.
89
90 void close();
91 /// Closes the socket.
92
93 static int select(SocketList& readList, SocketList& writeList, SocketList& exceptList, const Poco::Timespan& timeout);
94 /// Determines the status of one or more sockets,
95 /// using a call to select().
96 ///
97 /// ReadList contains the list of sockets which should be
98 /// checked for readability.
99 ///
100 /// WriteList contains the list of sockets which should be
101 /// checked for writeability.
102 ///
103 /// ExceptList contains a list of sockets which should be
104 /// checked for a pending error.
105 ///
106 /// Returns the number of sockets ready.
107 ///
108 /// After return,
109 /// * readList contains those sockets ready for reading,
110 /// * writeList contains those sockets ready for writing,
111 /// * exceptList contains those sockets with a pending error.
112 ///
113 /// If the total number of sockets passed in readList, writeList and
114 /// exceptList is zero, select() will return immediately and the
115 /// return value will be 0.
116 ///
117 /// If one of the sockets passed to select() is closed while
118 /// select() runs, select will return immediately. However,
119 /// the closed socket will not be included in any list.
120 /// In this case, the return value may be greater than the sum
121 /// of all sockets in all list.
122
123 bool poll(const Poco::Timespan& timeout, int mode) const;
124 /// Determines the status of the socket, using a
125 /// call to poll() or select().
126 ///
127 /// The mode argument is constructed by combining the values
128 /// of the SelectMode enumeration.
129 ///
130 /// Returns true if the next operation corresponding to
131 /// mode will not block, false otherwise.
132
133 int available() const;
134 /// Returns the number of bytes available that can be read
135 /// without causing the socket to block.
136
137 void setSendBufferSize(int size);
138 /// Sets the size of the send buffer.
139
140 int getSendBufferSize() const;
141 /// Returns the size of the send buffer.
142 ///
143 /// The returned value may be different than the
144 /// value previously set with setSendBufferSize(),
145 /// as the system is free to adjust the value.
146
147 void setReceiveBufferSize(int size);
148 /// Sets the size of the receive buffer.
149
150 int getReceiveBufferSize() const;
151 /// Returns the size of the receive buffer.
152 ///
153 /// The returned value may be different than the
154 /// value previously set with setReceiveBufferSize(),
155 /// as the system is free to adjust the value.
156
157 void setSendTimeout(const Poco::Timespan& timeout);
158 /// Sets the send timeout for the socket.
159
160 Poco::Timespan getSendTimeout() const;
161 /// Returns the send timeout for the socket.
162 ///
163 /// The returned timeout may be different than the
164 /// timeout previously set with setSendTimeout(),
165 /// as the system is free to adjust the value.
166
167 void setReceiveTimeout(const Poco::Timespan& timeout);
168 /// Sets the send timeout for the socket.
169 ///
170 /// On systems that do not support SO_RCVTIMEO, a
171 /// workaround using poll() is provided.
172
173 Poco::Timespan getReceiveTimeout() const;
174 /// Returns the receive timeout for the socket.
175 ///
176 /// The returned timeout may be different than the
177 /// timeout previously set with getReceiveTimeout(),
178 /// as the system is free to adjust the value.
179
180 void setOption(int level, int option, int value);
181 /// Sets the socket option specified by level and option
182 /// to the given integer value.
183
184 void setOption(int level, int option, unsigned value);
185 /// Sets the socket option specified by level and option
186 /// to the given integer value.
187
188 void setOption(int level, int option, unsigned char value);
189 /// Sets the socket option specified by level and option
190 /// to the given integer value.
191
192 void setOption(int level, int option, const Poco::Timespan& value);
193 /// Sets the socket option specified by level and option
194 /// to the given time value.
195
196 void setOption(int level, int option, const IPAddress& value);
197 /// Sets the socket option specified by level and option
198 /// to the given time value.
199
200 void getOption(int level, int option, int& value) const;
201 /// Returns the value of the socket option
202 /// specified by level and option.
203
204 void getOption(int level, int option, unsigned& value) const;
205 /// Returns the value of the socket option
206 /// specified by level and option.
207
208 void getOption(int level, int option, unsigned char& value) const;
209 /// Returns the value of the socket option
210 /// specified by level and option.
211
212 void getOption(int level, int option, Poco::Timespan& value) const;
213 /// Returns the value of the socket option
214 /// specified by level and option.
215
216 void getOption(int level, int option, IPAddress& value) const;
217 /// Returns the value of the socket option
218 /// specified by level and option.
219
220 void setLinger(bool on, int seconds);
221 /// Sets the value of the SO_LINGER socket option.
222
223 void getLinger(bool& on, int& seconds) const;
224 /// Returns the value of the SO_LINGER socket option.
225
226 void setNoDelay(bool flag);
227 /// Sets the value of the TCP_NODELAY socket option.
228
229 bool getNoDelay() const;
230 /// Returns the value of the TCP_NODELAY socket option.
231
232 void setKeepAlive(bool flag);
233 /// Sets the value of the SO_KEEPALIVE socket option.
234
235 bool getKeepAlive() const;
236 /// Returns the value of the SO_KEEPALIVE socket option.
237
238 void setReuseAddress(bool flag);
239 /// Sets the value of the SO_REUSEADDR socket option.
240
241 bool getReuseAddress() const;
242 /// Returns the value of the SO_REUSEADDR socket option.
243
244 void setReusePort(bool flag);
245 /// Sets the value of the SO_REUSEPORT socket option.
246 /// Does nothing if the socket implementation does not
247 /// support SO_REUSEPORT.
248
249 bool getReusePort() const;
250 /// Returns the value of the SO_REUSEPORT socket option.
251 ///
252 /// Returns false if the socket implementation does not
253 /// support SO_REUSEPORT.
254
255 void setOOBInline(bool flag);
256 /// Sets the value of the SO_OOBINLINE socket option.
257
258 bool getOOBInline() const;
259 /// Returns the value of the SO_OOBINLINE socket option.
260
261 void setBlocking(bool flag);
262 /// Sets the socket in blocking mode if flag is true,
263 /// disables blocking mode if flag is false.
264
265 bool getBlocking() const;
266 /// Returns the blocking mode of the socket.
267 /// This method will only work if the blocking modes of
268 /// the socket are changed via the setBlocking method!
269
270 SocketAddress address() const;
271 /// Returns the IP address and port number of the socket.
272
273 SocketAddress peerAddress() const;
274 /// Returns the IP address and port number of the peer socket.
275
276 SocketImpl* impl() const;
277 /// Returns the SocketImpl for this socket.
278
279 bool secure() const;
280 /// Returns true iff the socket's connection is secure
281 /// (using SSL or TLS).
282
283 static bool supportsIPv4();
284 /// Returns true if the system supports IPv4.
285
286 static bool supportsIPv6();
287 /// Returns true if the system supports IPv6.
288
289 void init(int af);
290 /// Creates the underlying system socket for the given
291 /// address family.
292 ///
293 /// Normally, this method should not be called directly, as
294 /// socket creation will be handled automatically. There are
295 /// a few situations where calling this method after creation
296 /// of the Socket object makes sense. One example is setting
297 /// a socket option before calling bind() on a ServerSocket.
298
299 static SocketBuf makeBuffer(void* buffer, std::size_t length);
300 /// Creates and returns buffer. Suitable for creating
301 /// the appropriate buffer for the platform.
302
303 static SocketBufVec makeBufVec(std::size_t size, std::size_t bufLen);
304 /// Creates and returns a vector of requested size, with
305 /// allocated buffers and lengths set accordingly.
306 /// This utility function works well when all buffers are
307 /// of same size.
308
309 static void destroyBufVec(SocketBufVec& buf);
310 /// Releases the memory pointed to by vector members
311 /// and shrinks the vector to size 0.
312 /// The vector must be created by makeBufVec(size_t, size_t).
313
314 static SocketBufVec makeBufVec(const std::vector<char*>& vec);
315 /// Creates and returns a vector of requested size, with
316 /// buffers pointing to the supplied data (so, `vec` must
317 /// remain available at the time of use) and lengths set
318 /// accordingly.
319 /// Notes:
320 /// - data length is determined using `strlen`, so this
321 /// function is not meant to be used with binary data.
322 ///
323 /// - if the returned buffer is used for read operations
324 /// (ie. operations that write to the bufer), pointing
325 /// to string literals will result in undefined behavior,
326 /// in best case an I/O error and subsequent exception
327
328 static SocketBufVec makeBufVec(const std::vector<std::string>& vec);
329 /// Creates and returns a vector of requested size, with
330 /// buffers pointing to the supplied data (so, `vec` must
331 /// remain available at the time of use) and lengths set
332 /// accordingly.
333 /// Note:: this function is not suitable for creation
334 /// of buffers used for writing (ie. reading from socket
335 /// into buffers).
336
337protected:
338 Socket(SocketImpl* pImpl);
339 /// Creates the Socket and attaches the given SocketImpl.
340 /// The socket takes ownership of the SocketImpl.
341
342 poco_socket_t sockfd() const;
343 /// Returns the socket descriptor for this socket.
344
345private:
346
347#if defined(POCO_HAVE_FD_POLL)
348class FDCompare
349 /// Utility functor used to compare socket file descriptors.
350 /// Used in poll() member function.
351{
352public:
353 FDCompare(int fd): _fd(fd) { }
354 inline bool operator()(const Socket& socket) const
355 { return socket.sockfd() == _fd; }
356
357private:
358 FDCompare();
359 int _fd;
360};
361#endif
362
363 SocketImpl* _pImpl;
364};
365
366
367//
368// inlines
369//
370inline bool Socket::operator == (const Socket& socket) const
371{
372 return _pImpl == socket._pImpl;
373}
374
375
376inline bool Socket::operator != (const Socket& socket) const
377{
378 return _pImpl != socket._pImpl;
379}
380
381
382inline bool Socket::operator < (const Socket& socket) const
383{
384 return _pImpl < socket._pImpl;
385}
386
387
388inline bool Socket::operator <= (const Socket& socket) const
389{
390 return _pImpl <= socket._pImpl;
391}
392
393
394inline bool Socket::operator > (const Socket& socket) const
395{
396 return _pImpl > socket._pImpl;
397}
398
399
400inline bool Socket::operator >= (const Socket& socket) const
401{
402 return _pImpl >= socket._pImpl;
403}
404
405
406inline void Socket::close()
407{
408 _pImpl->close();
409}
410
411
412inline bool Socket::poll(const Poco::Timespan& timeout, int mode) const
413{
414 return _pImpl->poll(timeout, mode);
415}
416
417
418inline int Socket::available() const
419{
420 return _pImpl->available();
421}
422
423
424inline void Socket::setSendBufferSize(int size)
425{
426 _pImpl->setSendBufferSize(size);
427}
428
429
430inline int Socket::getSendBufferSize() const
431{
432 return _pImpl->getSendBufferSize();
433}
434
435
436inline void Socket::setReceiveBufferSize(int size)
437{
438 _pImpl->setReceiveBufferSize(size);
439}
440
441
442inline int Socket::getReceiveBufferSize() const
443{
444 return _pImpl->getReceiveBufferSize();
445}
446
447
448inline void Socket::setSendTimeout(const Poco::Timespan& timeout)
449{
450 _pImpl->setSendTimeout(timeout);
451}
452
453
454inline Poco::Timespan Socket::getSendTimeout() const
455{
456 return _pImpl->getSendTimeout();
457}
458
459
460inline void Socket::setReceiveTimeout(const Poco::Timespan& timeout)
461{
462 _pImpl->setReceiveTimeout(timeout);
463}
464
465
466inline Poco::Timespan Socket::getReceiveTimeout() const
467{
468 return _pImpl->getReceiveTimeout();
469}
470
471
472inline void Socket::setOption(int level, int option, int value)
473{
474 _pImpl->setOption(level, option, value);
475}
476
477
478inline void Socket::setOption(int level, int option, unsigned value)
479{
480 _pImpl->setOption(level, option, value);
481}
482
483
484inline void Socket::setOption(int level, int option, unsigned char value)
485{
486 _pImpl->setOption(level, option, value);
487}
488
489
490inline void Socket::setOption(int level, int option, const Poco::Timespan& value)
491{
492 _pImpl->setOption(level, option, value);
493}
494
495
496inline void Socket::setOption(int level, int option, const IPAddress& value)
497{
498 _pImpl->setOption(level, option, value);
499}
500
501
502inline void Socket::getOption(int level, int option, int& value) const
503{
504 _pImpl->getOption(level, option, value);
505}
506
507
508inline void Socket::getOption(int level, int option, unsigned& value) const
509{
510 _pImpl->getOption(level, option, value);
511}
512
513
514inline void Socket::getOption(int level, int option, unsigned char& value) const
515{
516 _pImpl->getOption(level, option, value);
517}
518
519
520inline void Socket::getOption(int level, int option, Poco::Timespan& value) const
521{
522 _pImpl->getOption(level, option, value);
523}
524
525
526inline void Socket::getOption(int level, int option, IPAddress& value) const
527{
528 _pImpl->getOption(level, option, value);
529}
530
531
532inline void Socket::setLinger(bool on, int seconds)
533{
534 _pImpl->setLinger(on, seconds);
535}
536
537
538inline void Socket::getLinger(bool& on, int& seconds) const
539{
540 _pImpl->getLinger(on, seconds);
541}
542
543
544inline void Socket::setNoDelay(bool flag)
545{
546 _pImpl->setNoDelay(flag);
547}
548
549
550inline bool Socket::getNoDelay() const
551{
552 return _pImpl->getNoDelay();
553}
554
555
556inline void Socket::setKeepAlive(bool flag)
557{
558 _pImpl->setKeepAlive(flag);
559}
560
561
562inline bool Socket::getKeepAlive() const
563{
564 return _pImpl->getKeepAlive();
565}
566
567
568inline void Socket::setReuseAddress(bool flag)
569{
570 _pImpl->setReuseAddress(flag);
571}
572
573
574inline bool Socket::getReuseAddress() const
575{
576 return _pImpl->getReuseAddress();
577}
578
579
580inline void Socket::setReusePort(bool flag)
581{
582 _pImpl->setReusePort(flag);
583}
584
585
586inline bool Socket::getReusePort() const
587{
588 return _pImpl->getReusePort();
589}
590
591
592inline void Socket::setOOBInline(bool flag)
593{
594 _pImpl->setOOBInline(flag);
595}
596
597
598inline bool Socket::getOOBInline() const
599{
600 return _pImpl->getOOBInline();
601}
602
603
604inline void Socket::setBlocking(bool flag)
605{
606 _pImpl->setBlocking(flag);
607}
608
609
610inline bool Socket::getBlocking() const
611{
612 return _pImpl->getBlocking();
613}
614
615
616inline SocketImpl* Socket::impl() const
617{
618 return _pImpl;
619}
620
621
622inline poco_socket_t Socket::sockfd() const
623{
624 return _pImpl->sockfd();
625}
626
627
628inline SocketAddress Socket::address() const
629{
630 return _pImpl->address();
631}
632
633
634inline SocketAddress Socket::peerAddress() const
635{
636 return _pImpl->peerAddress();
637}
638
639
640inline bool Socket::secure() const
641{
642 return _pImpl->secure();
643}
644
645
646inline bool Socket::supportsIPv4()
647{
648 return true;
649}
650
651
652inline bool Socket::supportsIPv6()
653{
654#if defined(POCO_HAVE_IPv6)
655 return true;
656#else
657 return false;
658#endif
659}
660
661
662inline void Socket::init(int af)
663{
664 _pImpl->init(af);
665}
666
667
668} } // namespace Poco::Net
669
670
671#endif // Net_Socket_INCLUDED
672