|
| | TCPServer (Report *report=nullptr, bool non_blocking=false, Object *owner=nullptr) |
| | Constructor.
|
| |
| | TCPServer (ReporterBase *delegate, bool non_blocking=false, Object *owner=nullptr) |
| | Constructor.
|
| |
| virtual bool | accept (TCPConnection &client, IPSocketAddress &client_address, IOSB *iosb=nullptr) |
| | Wait for an incoming client connection.
|
| |
| void | addSubscription (SocketHandlerInterface *handler) |
| | Add a subscriber to open/close events.
|
| |
| bool | bind (const IPSocketAddress &addr) |
| | Bind to a local address and port.
|
| |
| void | cancelSubscription (SocketHandlerInterface *handler) |
| | Remove a subscriber to open/close events.
|
| |
| virtual bool | close (bool silent=false) final |
| | Close the socket.
|
| |
| IP | generation () const |
| | Get the IP generation with which the socket was open.
|
| |
| bool | getLocalAddress (IPSocketAddress &addr) const |
| | Get local socket address.
|
| |
| SysSocketType | getSocket () const |
| | Get the underlying socket device handle (use with care).
|
| |
| bool | isNonBlocking () const |
| | Check if the device is in non-blocking mode.
|
| |
| bool | isOpen () const |
| | Check if socket is open.
|
| |
| bool | isOwned () |
| | Check if the object is owned.
|
| |
template<class OBJECT >
requires std::derived_from<OBJECT, ts::Object> |
| bool | isOwned () |
| | Check if the object is owned by an object of a given type.
|
| |
| virtual bool | listen (int backlog) |
| | Start the server.
|
| |
| UString | localName () |
| | Get the local address as a string.
|
| |
| bool | muteReport (bool mute) |
| | Temporarily mute the associated report.
|
| |
| virtual bool | open (IP gen=IP::Any) final |
| | Open the socket.
|
| |
| Object * | owner () |
| | Get the address of the optional "owner" object which was specified in the constructor.
|
| |
template<class OBJECT >
requires std::derived_from<OBJECT, ts::Object> |
| OBJECT * | owner () |
| | Get the address of the "owner" object which was specified in the constructor.
|
| |
| Report & | report () const |
| | Access the Report which is associated with this object.
|
| |
| bool | reusePort (bool reuse_port) |
| | Set the "reuse port" option.
|
| |
| bool | setAcceptStatus (TCPConnection &client, IPSocketAddress &client_address, IOSB *iosb) |
| | Update the status of an asynchronous accept().
|
| |
| bool | setKeepAlive (bool active) |
| | Set the "keep alive" option.
|
| |
| bool | setLingerTime (int seconds) |
| | Set the linger time option.
|
| |
| bool | setNoDelay (bool active) |
| | Set the "no delay" option.
|
| |
| bool | setNoLinger () |
| | Remove the linger time option.
|
| |
| bool | setNonBlocking (bool non_blocking) |
| | Set the device in non-blocking mode.
|
| |
| bool | setReceiveBufferSize (size_t size) |
| | Set the receive buffer size.
|
| |
| bool | setReceiveTimeout (cn::milliseconds timeout) |
| | Set the receive timeout.
|
| |
| Report * | setReport (Report *report) |
| | Associate this object with another Report to log errors.
|
| |
| ReporterBase * | setReport (ReporterBase *delegate) |
| | Associate this object with another ReporterBase to log errors.
|
| |
| bool | setSendBufferSize (size_t size) |
| | Set the send buffer size.
|
| |
| bool | setTTL (int ttl) |
| | Set the Time To Live (TTL) option.
|
| |
|
| virtual bool | allowSetNonBlocking () const override |
| | Check that the non-blocking mode can be set.
|
| |
| template<typename F > |
| void | callSubscribers (F &&func) |
| | Call a handler on all subscribers, using a lambda expression.
|
| |
| bool | checkNonBlocking (bool non_blocking, const UChar *opname) |
| | Check the blocking mode of a device.
|
| |
| bool | checkNonBlocking (IOSB *iosb, const UChar *opname) |
| | Check the blocking mode of a device.
|
| |
| virtual bool | closeImplementation (bool silent) override |
| | Close the socket, actual implementation which may be overriden by subclasses.
|
| |
| bool | convert (IPAddress &addr) const |
| | Convert an IP address to make it compatible with the socket IP generation.
|
| |
| bool | createSocket (IP gen, int type, int protocol) |
| | Create the socket.
|
| |
| virtual void | declareOpened (SysSocketType sock) override |
| | Set an open socket descriptor from a subclass.
|
| |
| virtual bool | openImplementation (IP gen) override |
| | Open the socket, actual implementation which must be overriden by subclasses.
|
| |
| bool | setSystemNonBlocking (SysSocketType fd, bool non_blocking) |
| | Low-level method to set a system file or socket descriptor in non-blocking mode.
|
| |
Implementation of a TCP/IP server.
The following lists the typical server-side scenario in the correct order. Many steps such as setting socket options are optional. The symbol [*] means mandatory. Depending on the platform, some options settings are sensitive to the order. The following order has proven to work on most platforms.
Invoking close() is optional since the destructor of the class will properly close the socket if not already done.
| virtual bool ts::TCPServer::listen |
( |
int |
backlog | ) |
|
|
virtual |
Start the server.
Here, starting the server means starting to listen to incoming client connections. Internally to the kernel, the incoming connections are queued up to backlog. When the method accept() is invoked and some incoming connections are already queued in the kernel, the oldest one is immediately accepted. Otherwise, accept() blocks until a new incoming connection arrives.
- Parameters
-
| [in] | backlog | Maximum number of incoming connections which allowed to queue in the kernel until the next call to accept(). Note that this value is a minimum queue size. But the kernel may accept more. There is no guarantee that additional incoming connections will be rejected if more than backlog are already queueing. |
- Returns
- True on success, false on error.
Reimplemented in ts::TLSServer.
| virtual bool ts::TCPServer::closeImplementation |
( |
bool |
silent | ) |
|
|
overrideprotectedvirtual |
Close the socket, actual implementation which may be overriden by subclasses.
Never called when the application tries to close a socket which is not open. If overridden by a subclass, the superclass must be called at the end of the overridden close().
- Parameters
-
| [in] | silent | If true, do not report errors through the logger. This is typically useful when the socket is in some error condition and closing it is necessary although it may generate additional meaningless errors. |
- Returns
- True on success, false on error.
Reimplemented from ts::TCPSocket.
Reimplemented in ts::TLSServer.
Bind to a local address and port.
The IP address part of the socket address must one of:
- IPAddress::AnyAddress4.
- UDP: Any local interface may be used to send or receive UDP datagrams. For each outgoing packet, the actual interface is selected by the kernel based on the routing rules. Incoming UDP packets for the selected port will be accepted from any local interface.
- TCP client: Any local interface may be used to connect to a server.
- TCP server: Any local interface may be used to receive incoming client connections.
- The IP address of an interface of the local system.
- UDP: Outgoing packets will be unconditionally sent through this interface. Incoming UDP packets for the selected port will be accepted only when they arrive through the selected interface.
- TCP client: Outgoing connections will be only allowed through this interface.
- TCP server: Incoming client connections will be accepted only when they arrive through the selected interface.
Special note for receiving multicast on most Unix systems (at least Linux and macOS): The IP address shall be either AnyAddress4 or the multicast group address. Do not specify a local address to receive multicast on Unix.
The port number part of the socket address must be one of:
- IPSocketAddress::AnyPort. The socket is bound to an arbitrary unused local UDP or TCP port. This is the usual configuration for a TCP client.
- A specific port number. If this UDP or TCP port is already bound by another local socket of the same type, the bind operation fails, unless the "reuse port" option has already been set.
- Parameters
-
| [in] | addr | Local socket address to bind to. |
- Returns
- True on success, false on error.
| bool ts::NonBlockingDevice::setSystemNonBlocking |
( |
SysSocketType |
fd, |
|
|
bool |
non_blocking |
|
) |
| |
|
protectedinherited |
Low-level method to set a system file or socket descriptor in non-blocking mode.
- Parameters
-
| [in] | fd | System file or socket descriptor. |
| [in] | non_blocking | It true, the device is set in non-blocking mode. |
- Returns
- True on success, false on error.
Summary: Do not use this method unless you exactly know what you are doing.
UNIX: Depending on the way a file descriptor is created, it may be possible to specify the non-blocking mode from the beginning. Or it can be somehow inherited. However, this is not portable.
Examples:
- On Linux and FreeBSD, a socket can be directly created in non-blocking mode using the flag SOCK_NONBLOCK in the 'type' parameter of the socket() system call. However, it does not work on macOS.
- On macOS (and maybe FreeBSD), when a server socket is in non-blocking mode, all client session sockets which are created by accept() are also in non-blocking mode. However, on Linux, they are in blocking mode.
In all cases, it is possible to set a file descriptor in non-blocking mode at any time using the method setSystemNonBlocking(). This method uses fcntl(F_SETFL) to alter the file descriptor's flags.
Windows: The natural way of not being blocked on I/O on Windows is asynchronous I/O. To increase the general confusion, there is some form of non-blocking mode on Windows sockets, and only sockets, not other forms of file handles. This mode is activated using "ioctlsocket(fd, FIONBIO, &mode)". When this mode is active, socket I/O become similar to UNIX: they immediately either succeed or fail, but never block. However, there is no way to get notified when the I/O becomes possible. There is no equivalent to epoll (Linux) or kqueue (macOS and BSD). The Windows I/O Completion Ports can only work on asynchronous I/O, using OVERLAPPED structures. Because this form of non-blocking mode is mostly useless in practice, we do not use it and the method setSystemNonBlocking() does nothing on Windows.
- See also
- https://learn.microsoft.com/en-us/archive/blogs/csliu/io-concept-blockingnon-blocking-vs-syncasync
| static int ts::ReporterBase::SilentLevel |
( |
bool |
silent | ) |
|
|
inlinestaticinherited |
Compute a log severity level from a "silent" parameter.
Some subclass methods have a "silent" parameter to avoid reporting errors which may be insignificant, typically when closing a device after an error, in which case the close operation may produce other errors if the previous error left the device in an inconsistent state. While those errors should not be displayed as errors, we still display them at debug level.
- Parameters
-
| [in] | silent | If true, do not report errors, report debug messages instead. |
- Returns
- Error when silent is false, Debug otherwise.