![]() |
jsocketpp 1.0
A cross-platform C++20 socket library.
|
Classes and functions for TCP networking. More...
Classes | |
class | jsocketpp::ServerSocket |
TCP server socket abstraction for cross-platform C++ networking. More... | |
class | jsocketpp::Socket |
TCP client connection abstraction (Java-like interface). More... |
Functions | |
jsocketpp::ServerSocket::ServerSocket (Port port, std::string_view localAddress={}, bool autoBindListen=true, bool reuseAddress=true, int soTimeoutMillis=-1, bool dualStack=true) | |
Constructs a ServerSocket for listening to incoming TCP connections with full configuration control. | |
std::string | jsocketpp::ServerSocket::getInetAddress () const |
Get the local IP address to which the server socket is bound. | |
Port | jsocketpp::ServerSocket::getLocalPort () const |
Retrieve the local port number to which the server socket is bound. | |
std::string | jsocketpp::ServerSocket::getLocalSocketAddress () const |
Get the local socket address (IP and port) to which the server socket is bound. | |
jsocketpp::ServerSocket::ServerSocket (const ServerSocket &rhs)=delete | |
Copy constructor (deleted). | |
ServerSocket & | jsocketpp::ServerSocket::operator= (const ServerSocket &rhs)=delete |
Copy assignment operator (deleted). | |
jsocketpp::ServerSocket::ServerSocket (ServerSocket &&rhs) noexcept | |
Move constructor that transfers ownership of server socket resources. | |
ServerSocket & | jsocketpp::ServerSocket::operator= (ServerSocket &&rhs) noexcept |
Move assignment operator for ServerSocket. | |
jsocketpp::ServerSocket::~ServerSocket () noexcept | |
Destructor that automatically closes the server socket and releases all associated resources. | |
void | jsocketpp::ServerSocket::bind () |
Binds the server socket to the configured port and network interface. | |
bool | jsocketpp::ServerSocket::isBound () const noexcept |
Check if the server socket is bound to a local address. | |
void | jsocketpp::ServerSocket::listen (int backlog=128) |
Marks the socket as a passive (listening) socket, ready to accept incoming TCP connection requests. | |
bool | jsocketpp::ServerSocket::isListening () const noexcept |
Check if the server socket is currently listening for incoming connections. | |
Socket | jsocketpp::ServerSocket::accept (std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) const |
Accept an incoming client connection, respecting the configured socket timeout. | |
Socket | jsocketpp::ServerSocket::accept (int timeoutMillis, std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) const |
Accept an incoming client connection, waiting up to the specified timeout. | |
std::optional< Socket > | jsocketpp::ServerSocket::tryAccept (std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) const |
Attempt to accept an incoming client connection, returning immediately or after the configured timeout. | |
std::optional< Socket > | jsocketpp::ServerSocket::tryAccept (int timeoutMillis, std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) const |
Attempt to accept an incoming client connection, waiting up to a specified timeout. | |
Socket | jsocketpp::ServerSocket::acceptBlocking (std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) const |
Accept an incoming client connection, always blocking until a client connects (unless the socket is set to non-blocking). | |
std::optional< Socket > | jsocketpp::ServerSocket::acceptNonBlocking (std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) const |
Attempt to accept a client connection in non-blocking fashion. | |
std::future< Socket > | jsocketpp::ServerSocket::acceptAsync (std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) const |
Asynchronously accept an incoming client connection, returning a future. | |
void | jsocketpp::ServerSocket::acceptAsync (std::function< void(std::optional< Socket >, std::exception_ptr)> callback, std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) const |
Asynchronously accept a client connection and invoke a callback upon completion. | |
void | jsocketpp::ServerSocket::close () |
Closes the server socket and releases its associated system resources. | |
bool | jsocketpp::ServerSocket::isValid () const noexcept |
Check whether the server socket is currently open and valid. | |
bool | jsocketpp::ServerSocket::isClosed () const noexcept |
Check if the server socket has been closed. | |
void | jsocketpp::ServerSocket::setOption (int level, int optName, int value) |
Set a socket option for the listening server socket. | |
int | jsocketpp::ServerSocket::getOption (int level, int optName) const |
Retrieve the current value of a socket option for the listening server socket. | |
static int | jsocketpp::ServerSocket::getSocketReuseOption () |
Returns the correct socket option constant for address reuse, depending on the platform. | |
void | jsocketpp::ServerSocket::setReuseAddress (bool enable) |
Enable or disable address reuse for this server socket. | |
bool | jsocketpp::ServerSocket::getReuseAddress () const |
Query whether the address reuse option is enabled on this server socket. | |
void | jsocketpp::ServerSocket::setNonBlocking (bool nonBlocking) |
Set the server socket to non-blocking or blocking mode. | |
bool | jsocketpp::ServerSocket::getNonBlocking () const |
Check if the server socket is in non-blocking mode. | |
bool | jsocketpp::ServerSocket::waitReady (std::optional< int > timeoutMillis=std::nullopt) const |
Wait for the server socket to become ready to accept an incoming connection. | |
void | jsocketpp::ServerSocket::setSoTimeout (const int timeoutMillis) |
Set the logical timeout (in milliseconds) for accepting client connections. | |
int | jsocketpp::ServerSocket::getSoTimeout () const noexcept |
Get the logical timeout (in milliseconds) for accept operations. | |
void | jsocketpp::ServerSocket::setIPv6Only (bool enable) |
Enable or disable IPv6-only mode for this server socket. | |
bool | jsocketpp::ServerSocket::getIPv6Only () const |
Query whether IPv6-only mode is enabled. | |
void | jsocketpp::ServerSocket::setDefaultReceiveBufferSize (const std::size_t size) |
Set the default receive buffer size for accepted client sockets. | |
std::size_t | jsocketpp::ServerSocket::getDefaultReceiveBufferSize () const noexcept |
Get the current default receive buffer size for accepted client sockets. | |
void | jsocketpp::ServerSocket::setDefaultSendBufferSize (const std::size_t size) |
Set the default send buffer size for accepted client sockets. | |
std::size_t | jsocketpp::ServerSocket::getDefaultSendBufferSize () const noexcept |
Get the current default send buffer size for accepted client sockets. | |
void | jsocketpp::ServerSocket::setDefaultInternalBufferSize (const std::size_t size) |
Set the per-instance default internal buffer size used for buffered read operations. | |
std::size_t | jsocketpp::ServerSocket::getDefaultInternalBufferSize () const noexcept |
Get the per-instance default internal buffer size used for buffered read operations. | |
void | jsocketpp::ServerSocket::setReusePort (bool enable) |
Enable or disable the SO_REUSEPORT socket option. | |
bool | jsocketpp::ServerSocket::getReusePort () const |
Query whether SO_REUSEPORT is enabled for this socket. | |
SOCKET | jsocketpp::ServerSocket::getHandle () const |
Get the underlying native socket handle/descriptor. | |
void | jsocketpp::ServerSocket::cleanupAndThrow (int errorCode) |
Cleans up server socket resources and throws a SocketException. | |
std::size_t | jsocketpp::ServerSocket::getEffectiveReceiveBufferSize (const std::optional< std::size_t > recvBufferSize) const |
Get the effective receive buffer size to use for socket read operations. | |
std::size_t | jsocketpp::ServerSocket::getEffectiveSendBufferSize (std::optional< std::size_t > sendBufferSize) const |
Get the effective send buffer size to use for socket write operations. | |
std::size_t | jsocketpp::ServerSocket::getEffectiveInternalBufferSize (std::optional< std::size_t > internalBufferSize) const |
Get the effective internal buffer size to use for buffered socket read operations. | |
std::tuple< std::size_t, std::size_t, std::size_t > | jsocketpp::ServerSocket::resolveBuffers (const std::optional< std::size_t > recv, const std::optional< std::size_t > send, const std::optional< std::size_t > internal) const |
Resolves effective receive and send buffer sizes from optional user inputs. | |
jsocketpp::Socket::Socket (SOCKET client, const sockaddr_storage &addr, socklen_t len, std::size_t recvBufferSize, std::size_t sendBufferSize, std::size_t internalBufferSize) | |
Protected constructor used internally to create Socket objects for accepted client connections. | |
jsocketpp::Socket::Socket ()=delete | |
Default constructor (deleted) for Socket class. | |
jsocketpp::Socket::Socket (std::string_view host, Port port, std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) | |
Creates a new Socket object configured to connect to the specified host and port. | |
jsocketpp::Socket::Socket (const Socket &rhs)=delete | |
Copy constructor (deleted) for Socket class. | |
jsocketpp::Socket::Socket (Socket &&rhs) noexcept | |
Move constructor that transfers ownership of socket resources. | |
Socket & | jsocketpp::Socket::operator= (const Socket &rhs)=delete |
Copy assignment operator (deleted) for Socket class. | |
Socket & | jsocketpp::Socket::operator= (Socket &&rhs) noexcept |
Move assignment operator that transfers socket ownership safely. | |
jsocketpp::Socket::~Socket () noexcept | |
Destructs the Socket object, closing connections and freeing resources. | |
std::string | jsocketpp::Socket::getRemoteSocketAddress (bool convertIPv4Mapped=true) const |
Get the remote peer's address and port as a formatted string. | |
void | jsocketpp::Socket::connect (int timeoutMillis=-1) const |
Establishes a TCP connection to the remote host with optional timeout control. | |
template<typename T> | |
T | jsocketpp::Socket::read () |
Reads a fixed-size trivially copyable value of type T from the socket. | |
std::string | jsocketpp::Socket::readExact (std::size_t n) const |
Read exactly n bytes from the socket into a string. | |
std::string | jsocketpp::Socket::readUntil (char delimiter, std::size_t maxLen=8192, bool includeDelimiter=true) const |
Reads data from the socket until a specified delimiter character. | |
std::string | jsocketpp::Socket::readLine (const std::size_t maxLen=8192, const bool includeDelimiter=true) const |
Reads a line terminated by ' ' from the socket. | |
std::string | jsocketpp::Socket::readAtMost (std::size_t n) const |
Reads up to n bytes from the socket into a string. | |
std::size_t | jsocketpp::Socket::readInto (void *buffer, const std::size_t len) const |
Reads available data from the socket into the provided buffer. | |
std::size_t | jsocketpp::Socket::readIntoExact (void *buffer, const std::size_t len) const |
Reads exactly len bytes into the given buffer (looped recv). | |
std::string | jsocketpp::Socket::readAtMostWithTimeout (std::size_t n, int timeoutMillis) const |
Performs a best-effort read up to n bytes, with a maximum timeout. | |
template<typename T> | |
std::string | jsocketpp::Socket::readPrefixed () |
Reads a length-prefixed payload using a fixed-size prefix type. | |
template<typename T> | |
std::string | jsocketpp::Socket::readPrefixed (const std::size_t maxPayloadLen) |
Reads a length-prefixed message with an upper bound check. | |
std::string | jsocketpp::Socket::readAvailable () const |
Reads all bytes currently available on the socket without blocking. | |
std::size_t | jsocketpp::Socket::readIntoAvailable (void *buffer, std::size_t bufferSize) const |
Reads all currently available bytes into the provided buffer without blocking. | |
std::size_t | jsocketpp::Socket::readv (std::span< BufferView > buffers) const |
Performs a vectorized read into multiple buffers using a single system call. | |
std::size_t | jsocketpp::Socket::readvAll (std::span< BufferView > buffers) const |
Reads exactly the full contents of all provided buffers. | |
std::size_t | jsocketpp::Socket::readvAllWithTotalTimeout (std::span< BufferView > buffers, int timeoutMillis) const |
Reads exactly the full contents of all buffers within a timeout. | |
std::size_t | jsocketpp::Socket::readvAtMostWithTimeout (std::span< BufferView > buffers, int timeoutMillis) const |
Attempts a single vectorized read into multiple buffers with a timeout. | |
std::string | jsocketpp::Socket::peek (std::size_t n) const |
Peeks at incoming data without consuming it. | |
void | jsocketpp::Socket::discard (std::size_t n, std::size_t chunkSize=1024) const |
Discards exactly n bytes from the socket by reading and discarding them. | |
void | jsocketpp::Socket::close () |
Closes the socket connection and releases associated resources. | |
void | jsocketpp::Socket::shutdown (ShutdownMode how) const |
Shutdown specific communication aspects of the socket. | |
size_t | jsocketpp::Socket::write (std::string_view message) const |
Writes data to the socket, handling partial writes. | |
size_t | jsocketpp::Socket::writeAll (std::string_view message) const |
Writes the entire contents of a message to the socket, handling partial writes. | |
template<typename T> | |
std::size_t | jsocketpp::Socket::writePrefixed (const std::string &payload) |
Writes a length-prefixed payload using a fixed-size prefix type. | |
template<typename T> | |
std::size_t | jsocketpp::Socket::writePrefixed (const void *data, std::size_t len) const |
Writes a binary payload prefixed with its length using a fixed-size integer type. | |
std::size_t | jsocketpp::Socket::writev (std::span< const std::string_view > buffers) const |
Writes multiple buffers in a single system call using scatter/gather I/O. | |
std::size_t | jsocketpp::Socket::writevAll (std::span< const std::string_view > buffers) const |
Writes all buffers fully using vectorized I/O with automatic retry on partial sends. | |
std::size_t | jsocketpp::Socket::writeAtMostWithTimeout (std::string_view data, int timeoutMillis) const |
Performs a best-effort write with a total timeout. | |
std::size_t | jsocketpp::Socket::writeFrom (const void *data, std::size_t len) const |
Writes up to len bytes from a raw memory buffer in a single send call. | |
std::size_t | jsocketpp::Socket::writeFromAll (const void *data, std::size_t len) const |
Writes all bytes from a raw memory buffer, retrying until complete. | |
std::size_t | jsocketpp::Socket::writeWithTotalTimeout (std::string_view data, int timeoutMillis) const |
Writes the full payload with a total timeout across all retries. | |
std::size_t | jsocketpp::Socket::writevWithTotalTimeout (std::span< const std::string_view > buffers, int timeoutMillis) const |
Writes all buffers fully within a total timeout using vectorized I/O. | |
std::size_t | jsocketpp::Socket::writevFrom (std::span< const BufferView > buffers) const |
Writes multiple raw memory regions using vectorized I/O. | |
std::size_t | jsocketpp::Socket::writevFromAll (std::span< BufferView > buffers) const |
Writes all raw memory regions fully using scatter/gather I/O. | |
std::size_t | jsocketpp::Socket::writevFromWithTotalTimeout (std::span< BufferView > buffers, int timeoutMillis) const |
Writes all raw memory buffers fully within a timeout using scatter I/O. | |
void | jsocketpp::Socket::setReceiveBufferSize (std::size_t size) |
Sets the socket's receive buffer size (SO_RCVBUF). | |
void | jsocketpp::Socket::setSendBufferSize (std::size_t size) |
Sets the socket's send buffer size (SO_SNDBUF). | |
int | jsocketpp::Socket::getReceiveBufferSize () const |
Get the socket's receive buffer size (SO_RCVBUF). | |
int | jsocketpp::Socket::getSendBufferSize () const |
Get the socket's send buffer size (SO_SNDBUF). | |
void | jsocketpp::Socket::setInternalBufferSize (std::size_t newLen) |
Sets the size of the internal read buffer used for string operations. | |
bool | jsocketpp::Socket::isValid () const noexcept |
Check if the socket is valid and open for communication. | |
void | jsocketpp::Socket::setNonBlocking (bool nonBlocking) const |
Set the socket to non-blocking or blocking mode. | |
bool | jsocketpp::Socket::getNonBlocking () const |
Check if the socket is currently in non-blocking mode. | |
void | jsocketpp::Socket::setSoTimeout (int millis, bool forRead=true, bool forWrite=true) |
Set timeout for socket send and/or receive operations. | |
std::size_t | jsocketpp::Socket::readIntoInternal (void *buffer, std::size_t len, bool exact=false) const |
Reads data from the socket into a user-supplied buffer. | |
void | jsocketpp::Socket::cleanupAndThrow (int errorCode) |
Cleans up client socket resources and throws a SocketException. | |
template<> | |
std::string | jsocketpp::Socket::read () |
Template specialization to read a string from the socket. |
Classes and functions for TCP networking.
|
nodiscard |
Accept an incoming client connection, waiting up to the specified timeout.
Waits for an incoming client connection using the timeout specified by the timeoutMillis parameter:
Internally, this method uses waitReady(timeoutMillis) (which uses select()) to wait for readiness, then calls acceptBlocking() with the resolved buffer sizes. If the timeout expires with no client, a SocketTimeoutException is thrown.
The blocking or non-blocking mode of the server socket (via setNonBlocking()) does not affect the waiting behavior of this method, since select() is used for readiness detection.
[in] | timeoutMillis | Timeout in milliseconds to wait for a client connection:
|
[in] | recvBufferSize | The receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize(). |
[in] | sendBufferSize | The send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize(). |
[in] | internalBufferSize | The internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize(). |
SocketException | if the server socket is invalid or closed, or if an internal error occurs. |
SocketTimeoutException | if no client connects before the timeout expires. |
|
nodiscard |
Accept an incoming client connection, respecting the configured socket timeout.
Waits for an incoming client connection using the timeout value configured by setSoTimeout().
Internally, this method uses waitReady() (which internally uses select()) to wait for readiness and only then calls accept(). If the timeout expires with no client, a SocketTimeoutException is thrown.
The blocking or non-blocking mode of the server socket (via setNonBlocking()) does not affect the waiting behavior of this method, since select() is used for waiting.
[in] | recvBufferSize | The receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize(). |
[in] | sendBufferSize | The send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize(). |
[in] | internalBufferSize | The internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize(). |
SocketException | if the server socket is not initialized, closed, or if an internal error occurs. |
SocketTimeoutException | if the timeout expires before a client connects. |
void ServerSocket::acceptAsync | ( | std::function< void(std::optional< Socket >, std::exception_ptr)> | callback, |
std::optional< std::size_t > | recvBufferSize = std::nullopt, | ||
std::optional< std::size_t > | sendBufferSize = std::nullopt, | ||
std::optional< std::size_t > | internalBufferSize = std::nullopt ) const |
Asynchronously accept a client connection and invoke a callback upon completion.
Launches a background thread to perform an accept() operation and calls the user-provided callback when a client connects or an error occurs. This is useful for event-driven servers that require non-blocking, callback-based acceptance of new clients.
The callback is invoked exactly once with:
Internally, this uses a detached std::thread that invokes accept(...), wrapped in a try-catch block. If the server socket is not valid or an error occurs (including timeouts), the exception is captured and passed to the callback for inspection or rethrowing via std::rethrow_exception().
[in] | callback | Completion handler with signature: void callback(std::optional<Socket>, std::exception_ptr) |
[in] | recvBufferSize | The receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize(). |
[in] | sendBufferSize | The send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize(). |
[in] | internalBufferSize | The internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize(). |
|
nodiscard |
Asynchronously accept an incoming client connection, returning a future.
This method launches an asynchronous accept operation on the server socket, returning a std::future<Socket> that resolves once a client connects or an error occurs.
Internally, this uses std::async(std::launch::async, ...) to spawn a background thread that calls accept(...). The calling thread is never blocked.
When a client is accepted, the future becomes ready and yields a fully constructed Socket object. If an error or timeout occurs, the exception is rethrown when .get() is called on the future.
[in] | recvBufferSize | The receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize(). |
[in] | sendBufferSize | The send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize(). |
[in] | internalBufferSize | The internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize(). |
SocketException | if a fatal socket error occurs. |
SocketTimeoutException | if a timeout is configured and no client connects. |
|
nodiscard |
Accept an incoming client connection, always blocking until a client connects (unless the socket is set to non-blocking).
This method directly invokes the underlying system accept() on the listening socket.
[in] | recvBufferSize | The receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize(). |
[in] | sendBufferSize | The send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize(). |
[in] | internalBufferSize | The internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize(). |
SocketException | if the server socket is invalid or accept() fails (including with EWOULDBLOCK or EAGAIN in non-blocking mode). |
|
nodiscard |
Attempt to accept a client connection in non-blocking fashion.
This method attempts to accept an incoming client connection using the system accept() call:
This method does not use select(), poll(), or any timeout logic. It is ideal for event loops and polling-based architectures where you explicitly check for readiness before accepting.
[in] | recvBufferSize | The receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize(). |
[in] | sendBufferSize | The send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize(). |
[in] | internalBufferSize | The internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize(). |
SocketException | if the socket is invalid or accept() fails due to a system error (excluding EWOULDBLOCK / EAGAIN on non-blocking sockets). |
void ServerSocket::bind | ( | ) |
Binds the server socket to the configured port and network interface.
This method assigns a local address and port number to the socket, making it ready to accept incoming TCP connections.
SocketException | if the bind operation fails (for example, if the port is already in use or insufficient permissions). |
|
protected |
Cleans up server socket resources and throws a SocketException.
This method performs cleanup of the address information structures (_srvAddrInfo)
and throws a SocketException with the provided error code. It's typically called when an error occurs during socket initialization or configuration.
[in] | errorCode | The error code to include in the thrown exception |
SocketException | Always throws with the provided error code and corresponding message |
|
protected |
Cleans up client socket resources and throws a SocketException.
This method performs internal cleanup of the client socket's resources, including:
It is used to centralize error recovery during construction or connection setup, ensuring that all partially initialized resources are properly released before rethrowing an exception.
[in] | errorCode | The error code to report in the thrown exception. |
SocketException | Always throws, containing the error code and the corresponding human-readable error message obtained via SocketErrorMessage(errorCode). |
void ServerSocket::close | ( | ) |
Closes the server socket and releases its associated system resources.
This method closes the underlying server socket, making it no longer able to accept new client connections. After calling close(), the server socket enters the CLOSED state, and any further operations such as accept(), bind(), or listen() will fail with an exception.
Key details:
Example usage:
SocketException | If an error occurs while closing the socket (for example, if the underlying system call fails). |
void Socket::close | ( | ) |
Closes the socket connection and releases associated resources.
Close the socket.
This method performs an orderly shutdown and closure of the socket connection:
The method ensures proper cleanup even if the socket is already closed. After calling close(), the Socket object remains valid but disconnected (isValid() will return false).
SocketException | If the close operation fails due to:
|
SocketException | on error. |
void Socket::connect | ( | int | timeoutMillis = -1 | ) | const |
Establishes a TCP connection to the remote host with optional timeout control.
Attempts to establish a TCP connection to the remote host specified during Socket construction. The connection can be attempted in either blocking or non-blocking mode, depending on the timeout parameter.
[in] | timeoutMillis | Connection timeout in milliseconds:
|
SocketException | In cases of:
|
void Socket::discard | ( | std::size_t | n, |
std::size_t | chunkSize = 1024 ) const |
Discards exactly n bytes from the socket by reading and discarding them.
This method reads and discards n bytes from the socket without returning any data. It is useful in scenarios where part of the stream should be skipped (e.g., headers, fixed-length preambles, corrupted payloads).
The discard operation is performed using a temporary buffer of configurable size, which defaults to 1024 bytes. This chunk size is chosen as a balance between memory usage and I/O efficiency, but can be tuned for performance.
[in] | n | Number of bytes to discard. Must be greater than 0. |
[in] | chunkSize | Size (in bytes) of the temporary buffer used for reading/discarding. Default is 1024. |
SocketException | If the socket is invalid, an error occurs during recv(), or the connection is closed before all n bytes are discarded. |
|
inlinenodiscardnoexcept |
Get the per-instance default internal buffer size used for buffered read operations.
Returns the current value of _defaultInternalBufferSize, which is used as the fallback size for internal buffering in stream-oriented socket reads when no explicit buffer size is provided.
This value is typically initialized to DefaultBufferSize (4096 bytes), but can be modified using setDefaultInternalBufferSize().
|
inlinenodiscardnoexcept |
Get the current default receive buffer size for accepted client sockets.
Returns the buffer size that will be used when accepting new client connections. This is the value previously set by setDefaultReceiveBufferSize() or the default if not set.
|
inlinenodiscardnoexcept |
Get the current default send buffer size for accepted client sockets.
Returns the send buffer size that will be used when accepting new client connections. This is the value previously set by setDefaultSendBufferSize() or the default if not set.
|
inlinenodiscardprivate |
Get the effective internal buffer size to use for buffered socket read operations.
This helper determines the internal buffer size for read-related operations based on the provided optional value. If internalBufferSize is set, its value is returned directly. If not, the method returns the per-instance _defaultInternalBufferSize, which defaults to DefaultBufferSize (4096 bytes) unless explicitly overridden via setInternalBufferSize().
This internal buffer is used for stream-based operations (e.g. reading strings or protocol lines) and is distinct from the kernel-level socket buffers (SO_RCVBUF, SO_SNDBUF).
[in] | internalBufferSize | Optional buffer size override for a single operation. |
|
inlinenodiscardprivate |
Get the effective receive buffer size to use for socket read operations.
This helper determines the actual buffer size based on an optional user-provided value. If the parameter is std::nullopt, it returns the per-instance default receive buffer size; otherwise, it returns the explicitly provided value (even if it's 0).
[in] | recvBufferSize | Optional size. If unset, defaults to _defaultReceiveBufferSize. |
|
inlinenodiscardprivate |
Get the effective send buffer size to use for socket write operations.
This helper determines the actual send buffer size based on an optional user-specified value. If the parameter is std::nullopt, it returns the per-instance default send buffer size. Otherwise, it returns the explicitly specified size (including zero if the caller intends it).
[in] | sendBufferSize | Optional size. If unset, defaults to _defaultSendBufferSize. |
|
inlinenodiscard |
Get the underlying native socket handle/descriptor.
This method provides low-level access to the native socket handle (file descriptor on Unix-like systems, SOCKET handle on Windows) for advanced usage scenarios such as:
Improper use of the raw socket handle can lead to:
|
nodiscard |
Get the local IP address to which the server socket is bound.
Returns the string representation of the IP address (IPv4 or IPv6) the socket is bound to. Useful for debugging, especially when binding to specific interfaces or when binding to "0.0.0.0" or "::" (any address).
SocketException | if there is an error retrieving the address. |
|
nodiscard |
Query whether IPv6-only mode is enabled.
SocketException | if the socket is not IPv6, not open, or on system error. |
|
nodiscard |
Retrieve the local port number to which the server socket is bound.
This method returns the port number that the server socket is currently bound to. This is particularly useful when the socket is bound to port 0, which tells the operating system to automatically assign an available port. You can use this method after binding to discover the actual port being used.
SocketException | if there is an error retrieving the port number. |
|
nodiscard |
Get the local socket address (IP and port) to which the server socket is bound.
Returns a string with the IP address and port in the format "ip:port" (e.g., "127.0.0.1:8080"). Useful for debugging, logging, and displaying server status.
SocketException | if there is an error retrieving the address. |
|
nodiscard |
Check if the server socket is in non-blocking mode.
This function queries the socket's current blocking mode. In non-blocking mode, operations like accept() return immediately if no connection is available, instead of blocking.
SocketException | if the socket flags cannot be retrieved. |
|
nodiscard |
Check if the socket is currently in non-blocking mode.
Returns the current blocking mode of the socket. A socket in non-blocking mode will return immediately from operations that would normally block, such as connect(), read(), or write(), with an error code (usually EWOULDBLOCK/WSAEWOULDBLOCK) if the operation cannot be completed immediately.
SocketException | If:
|
|
nodiscard |
Retrieve the current value of a socket option for the listening server socket.
This method lets you query the current setting of a socket option on the listening socket. This is most useful for debugging, for monitoring server configuration, or for verifying a platform's default values.
Example: Get the current size of the receive buffer for new connections:
[in] | level | Protocol level (e.g., SOL_SOCKET) |
[in] | optName | Option name (e.g., SO_RCVBUF) |
SocketException | if the operation fails |
|
nodiscard |
Get the socket's receive buffer size (SO_RCVBUF).
Retrieves the current size of the operating system's receive buffer for this socket. The receive buffer is used by the OS to store incoming data before it is read by the application. A larger buffer can help prevent data loss during high-bandwidth transfers or when the application cannot read data quickly enough.
SocketException | If:
|
std::string Socket::getRemoteSocketAddress | ( | bool | convertIPv4Mapped = true | ) | const |
Get the remote peer's address and port as a formatted string.
Converts the remote peer's address information (stored in sockaddr_storage) to a human-readable string in the format "address:port". This method supports both IPv4 and IPv6 addresses and optionally handles IPv4-mapped IPv6 addresses.
The conversion process:
Example outputs:
[in] | convertIPv4Mapped | Whether to convert IPv4-mapped IPv6 addresses to pure IPv4 form. Default is true. |
SocketException | If address conversion fails or the socket is invalid. |
|
nodiscard |
Query whether the address reuse option is enabled on this server socket.
This function checks whether the socket is currently configured to allow reuse of local addresses.
SocketException | if the socket is not valid or the option cannot be retrieved. |
|
nodiscard |
Query whether SO_REUSEPORT is enabled for this socket.
This method returns the current status of the SO_REUSEPORT option on this socket. Like setReusePort(), this method is only available on platforms that define SO_REUSEPORT.
SocketException | if querying the option fails. |
|
nodiscard |
Get the socket's send buffer size (SO_SNDBUF).
Retrieves the current size of the operating system's send buffer for this socket. The send buffer is used by the OS to store outgoing data before it is transmitted over the network. A larger buffer can help improve performance during high-bandwidth transfers or when the network is temporarily congested.
SocketException | If:
|
|
staticnodiscard |
Returns the correct socket option constant for address reuse, depending on the platform.
SO_REUSEADDR
, which allows a socket to bind to a local address/port that is in the TIME_WAIT state. This is commonly used for servers that need to restart without waiting for TCP connections to fully time out.SO_EXCLUSIVEADDRUSE
, which provides safer server semantics: only one socket can bind to a given address/port at a time, but it allows quick server restarts. Using SO_REUSEADDR
on Windows has different (and less safe) behavior, potentially allowing multiple sockets to bind to the same port simultaneously, which is almost never what you want for TCP servers.
|
inlinenodiscardnoexcept |
Get the logical timeout (in milliseconds) for accept operations.
This value determines how long methods like accept() and tryAccept() will wait for an incoming client connection before timing out. It is used internally by select() or similar readiness mechanisms.
|
inlinenodiscardnoexcept |
Check if the server socket is bound to a local address.
Returns true if the socket has been successfully bound to a local address and port using the bind() method, or false otherwise. This means the socket has reserved a port but is not necessarily accepting connections yet.
Follows the naming and semantics of Java's ServerSocket::isBound().
|
inlinenodiscardnoexcept |
Check if the server socket has been closed.
This method returns true if the socket has been closed (and is no longer usable), or false if it is still open. The logic and naming follow the Java networking API for familiarity.
|
inlinenodiscardnoexcept |
Check if the server socket is currently listening for incoming connections.
Returns true if the socket has successfully entered the listening state by calling the listen() method, and is ready to accept new client connections. Returns false otherwise.
This complements isBound(), which only tells you if the socket has been bound to a local address.
|
inlinenodiscardnoexcept |
Check whether the server socket is currently open and valid.
This method determines if the server socket has been successfully created and is ready for binding, listening, or accepting connections. It checks whether the underlying socket handle is valid on the current platform.
|
inlinenodiscardnoexcept |
Check if the socket is valid and open for communication.
This method checks if the socket has a valid file descriptor and is ready for communication. A socket is considered valid if it has been successfully created and has not been closed. However, a valid socket is not necessarily connected; use isConnected() to check the connection status.
void ServerSocket::listen | ( | int | backlog = 128 | ) |
Marks the socket as a passive (listening) socket, ready to accept incoming TCP connection requests.
This method puts the server socket into listening mode, so it can accept incoming client connections using accept().
SocketException | if the listen operation fails. |
|
delete |
Copy assignment operator (deleted).
ServerSocket objects cannot be copied because they represent unique system resources. Each server socket needs exclusive ownership of its underlying file descriptor and associated resources. Use move semantics (operator=(ServerSocket&&)) instead to transfer ownership between ServerSocket objects.
[in] | rhs | The ServerSocket to copy from (unused since deleted) |
|
inlinenoexcept |
Move assignment operator for ServerSocket.
Transfers ownership of socket resources from another ServerSocket object to this one. If this socket already owns resources, they are properly cleaned up before the transfer.
The operation is noexcept and provides the strong exception guarantee:
After the move:
[in] | rhs | The ServerSocket to move resources from. |
Copy assignment operator (deleted) for Socket class.
This operator is explicitly deleted because Socket objects manage unique system resources (socket file descriptors) that cannot be safely duplicated. Each socket must have exclusive ownership of its underlying resources to prevent issues like:
Instead of copying, use move semantics (operator=(Socket&&)) to transfer ownership of a Socket from one object to another. For example:
[in] | rhs | The Socket object to copy from (unused since deleted) |
Move assignment operator that transfers socket ownership safely.
This operator safely transfers ownership of socket resources from another Socket object while properly managing the current socket's resources. It ensures proper cleanup of existing resources before taking ownership of the new ones.
The operator performs these steps in order:
After the move operation:
[in,out] | rhs | The source Socket whose resources will be moved. After the move, rhs will be left in a valid but disconnected state. |
std::string Socket::peek | ( | std::size_t | n | ) | const |
Peeks at incoming data without consuming it.
This method performs a non-destructive read of up to n bytes using the MSG_PEEK flag. It allows inspecting the contents of the socket's receive buffer without removing the data from the queue. This is useful for implementing lookahead parsing, protocol sniffing, or waiting for specific patterns before consuming data.
n | Maximum number of bytes to peek at. |
SocketException | If:
|
|
inline |
Reads a fixed-size trivially copyable value of type T from the socket.
Reads exactly sizeof(T) bytes from the socket and interprets them as a complete, binary-safe object of type T. This is useful for reading primitive values and POD (Plain Old Data) structs directly from the stream without any parsing logic.
T | The type to read from the socket. Must satisfy std::is_trivially_copyable. |
SocketException | If:
|
|
inline |
Template specialization to read a string from the socket.
Reads incoming data from the socket into the internal buffer and returns it as a string. This specialization provides string-specific functionality that differs from the generic read<T>() implementation.
SocketException | If:
|
std::string Socket::readAtMost | ( | std::size_t | n | ) | const |
Reads up to n bytes from the socket into a string.
Performs a single read operation from the socket, returning immediately with whatever data is available, up to the specified maximum number of bytes. This method provides a "best-effort" read that won't block waiting for more data once some data is available.
[in] | n | Maximum number of bytes to read in a single operation. The actual number of bytes read may be less than this value. |
SocketException | If:
|
std::string Socket::readAtMostWithTimeout | ( | std::size_t | n, |
int | timeoutMillis ) const |
Performs a best-effort read up to n bytes, with a maximum timeout.
Waits up to timeoutMillis milliseconds for the socket to become readable, then performs a single recv() call for at most n bytes.
Attempts to read up to n bytes from the socket, returning early if:
Unlike readExact(), this method returns as soon as any data is available, without waiting for the full requested length. The timeout applies to the initial wait for data availability.
[in] | n | Maximum number of bytes to read |
[in] | timeoutMillis | Maximum time to wait for data, in milliseconds:
|
SocketException | If:
|
std::string Socket::readAvailable | ( | ) | const |
Reads all bytes currently available on the socket without blocking.
Performs a best-effort, non-blocking read of all data that is already available in the socket's input buffer. This method uses platform-specific mechanisms (e.g., FIONREAD or ioctl) to query how many bytes can be read without blocking, then performs a single recv() call to consume and return that data.
This method is useful in event-driven or polling-based systems where you want to quickly drain the socket buffer without waiting for more data to arrive.
SocketException | If:
|
std::string Socket::readExact | ( | std::size_t | n | ) | const |
Read exactly n bytes from the socket into a string.
This method performs a blocking read operation that guarantees to read exactly the requested number of bytes, unless an error occurs. It will continue reading from the socket until all requested bytes are received, handling partial reads transparently.
[in] | n | Number of bytes to read. Must be greater than 0. |
SocketException | If:
|
|
inline |
Reads available data from the socket into the provided buffer.
Performs a "best-effort" read operation by attempting to read up to len bytes from the socket into the provided buffer. This method makes a single recv() call and returns immediately with whatever data is available, which may be less than the requested length.
[out] | buffer | Pointer to pre-allocated memory buffer to store read data. Must be valid and large enough for len bytes. |
[in] | len | Maximum number of bytes to read (buffer size) |
SocketException | If:
|
std::size_t Socket::readIntoAvailable | ( | void * | buffer, |
std::size_t | bufferSize ) const |
Reads all currently available bytes into the provided buffer without blocking.
This method checks how many bytes are available for reading on the socket using platform-specific ioctl/FIONREAD mechanisms, and reads as many bytes as possible (up to the specified buffer size) into the provided memory buffer. It does not block or wait for additional data to arrive.
This is the low-level, zero-copy variant of readAvailable(), ideal for high-performance applications and protocol parsers that manage their own memory buffers.
buffer | Pointer to the memory where received data will be stored. |
bufferSize | Maximum number of bytes to store in the buffer. |
SocketException | If:
|
|
inline |
Reads exactly len bytes into the given buffer (looped recv).
This method guarantees to read exactly the specified number of bytes from the socket into the provided buffer. It will continue reading until either all requested bytes are received or an error occurs. This is useful when reading fixed-length protocol messages or binary data structures where partial reads are not acceptable.
[out] | buffer | Pointer to pre-allocated memory where data should be written. Must be valid and large enough for len bytes. |
[in] | len | Number of bytes to read. Method won't return until exactly this many bytes are read or an error occurs. |
SocketException | If: |
|
protected |
Reads data from the socket into a user-supplied buffer.
This method provides direct access to the socket's receive functionality by reading data into a caller-provided buffer. It supports both "best-effort" single reads and exact-length reads that ensure all requested bytes are received.
[out] | buffer | Pointer to caller-allocated memory buffer Must be valid and large enough for len bytes |
[in] | len | Maximum number of bytes to read (buffer size) |
[in] | exact | If true, method won't return until len bytes are read or an error occurs |
SocketException | If:
|
|
inline |
Reads a line terminated by '
' from the socket.
This is a convenience method that calls readUntil('
', maxLen, includeDelimiter). It provides backward compatibility and a more intuitive interface for reading newline-terminated data.
maxLen | Maximum number of bytes to read (default: 8192) |
includeDelimiter | Whether to include the newline in the returned string (default: true) |
SocketException | on error or if line exceeds maxLen |
|
inline |
Reads a length-prefixed payload using a fixed-size prefix type.
Reads a message that consists of a length prefix followed by a variable-length payload. The prefix type T determines the format and size of the length field. This method is useful for protocols that encode message length as a fixed-size integer header.
+----------------+----------------------+ | Length (T) | Payload (n bytes) | +----------------+----------------------+ |<- sizeof(T) ->|<---- length ------->|
T | The unsigned integral type used for the length prefix (e.g., uint32_t). Must be a trivially copyable type. |
SocketException | If:
|
|
inline |
Reads a length-prefixed message with an upper bound check.
Reads a message that consists of a length prefix followed by a variable-length payload. This overload adds protection by validating that the decoded length does not exceed a specified maximum (maxPayloadLen), helping prevent corrupted or maliciously large payloads.
The prefix type T determines the format and size of the length field and is decoded in network byte order using net::fromNetwork().
+----------------+----------------------+ | Length (T) | Payload (n bytes) | +----------------+----------------------+ |<- sizeof(T) ->|<---- length ------->|
T | The unsigned integral type used for the length prefix (e.g., uint32_t). Must be a trivially copyable type. |
maxPayloadLen | Maximum allowed length of the decoded payload in bytes. If the decoded prefix exceeds this, an exception is thrown. |
SocketException | If:
|
std::string Socket::readUntil | ( | char | delimiter, |
std::size_t | maxLen = 8192, | ||
bool | includeDelimiter = true ) const |
Reads data from the socket until a specified delimiter character.
Reads data from the socket until the specified delimiter character is encountered. The method accumulates data efficiently, handling partial reads and buffer resizing as needed. The returned string optionally includes the delimiter character based on the includeDelimiter parameter.
[in] | delimiter | Character that marks the end of data |
[in] | maxLen | Maximum allowed data length in bytes (default: 8192) |
[in] | includeDelimiter | Whether to include delimiter in returned string (default: true) |
SocketException | If:
|
std::size_t Socket::readv | ( | std::span< BufferView > | buffers | ) | const |
Performs a vectorized read into multiple buffers using a single system call.
Reads data into the specified sequence of buffers using scatter/gather I/O. This method fills each buffer in order and returns the total number of bytes read. It is the counterpart to writev() and uses readv() or WSARecv() internally.
buffers | A span of BufferView objects describing writable regions. |
SocketException | If:
|
std::size_t Socket::readvAll | ( | std::span< BufferView > | buffers | ) | const |
Reads exactly the full contents of all provided buffers.
This method performs a reliable scatter read operation. It guarantees that all bytes described by the buffer span are filled by repeatedly calling readv() until the entire memory region is received or an error occurs.
buffers | A span of writable buffer views to fill completely. |
SocketException | If:
|
std::size_t Socket::readvAllWithTotalTimeout | ( | std::span< BufferView > | buffers, |
int | timeoutMillis ) const |
Reads exactly the full contents of all buffers within a timeout.
This method repeatedly performs vectorized reads into the given sequence of buffers until all bytes are read or the timeout expires. It uses a steady clock to track the total time spent across all retries.
buffers | Span of BufferView objects describing writable regions. |
timeoutMillis | Maximum allowed time to read all bytes (in milliseconds). |
SocketException | If:
|
std::size_t Socket::readvAtMostWithTimeout | ( | std::span< BufferView > | buffers, |
int | timeoutMillis ) const |
Attempts a single vectorized read into multiple buffers with a timeout.
Waits up to timeoutMillis for the socket to become readable, then performs a single readv() operation. May read less than the total buffer size. This is the timeout-aware version of readv(), useful for polling or best-effort I/O.
buffers | Writable buffer views to receive incoming data. |
timeoutMillis | Time to wait for readability before giving up. |
SocketException | If:
|
|
inlinenodiscardprivate |
Resolves effective receive and send buffer sizes from optional user inputs.
If either buffer size is not provided, this method falls back to the per-instance _defaultReceiveBufferSize or _defaultSendBufferSize.
recv | Optional receive buffer size. |
send | Optional send buffer size. |
internal | Optional internal buffer size. |
|
delete |
Copy constructor (deleted).
This constructor is explicitly deleted because ServerSocket instances manage unique system resources (socket descriptors) that cannot be safely shared or duplicated. Each socket must have exclusive ownership of its underlying system resources to ensure proper cleanup and avoid resource leaks.
Instead of copying, use move semantics (ServerSocket&&) to transfer ownership of a socket between objects.
[in] | rhs | The ServerSocket to copy from (unused since deleted). |
|
explicit |
Constructs a ServerSocket for listening to incoming TCP connections with full configuration control.
This constructor creates a TCP server socket that supports both IPv4 and IPv6, with flexible options for binding, listening, address selection, address reuse, accept timeouts, and dual-stack (IPv4+IPv6) control.
The constructor performs the following steps:
[in] | port | The port number to prepare the server socket for (binding will occur according to autoBindListen). |
[in] | localAddress | The local address/interface to bind to (empty for all interfaces). |
[in] | autoBindListen | If true (default), automatically binds and listens. If false, user must call them manually. |
[in] | reuseAddress | If true (default), enables address reuse (see above) before binding. |
[in] | soTimeoutMillis | Accept timeout in milliseconds for accept(); -1 (default) means block indefinitely. |
[in] | dualStack | If true (default), enables dual-stack (IPv4+IPv6) for IPv6 sockets. If false, enables IPv6-only mode (no IPv4-mapped addresses). Has no effect for IPv4 sockets. |
SocketException | If address resolution, socket creation, binding, or socket option configuration fails. |
|
inlinenoexcept |
Move constructor that transfers ownership of server socket resources.
This constructor implements move semantics to efficiently transfer ownership of socket resources from one ServerSocket object to another. It's particularly useful when you need to transfer socket ownership (e.g., returning from functions or storing in containers) without copying the underlying system resources.
The operation provides the strong exception guarantee and is marked noexcept:
After the move:
[in] | rhs | The ServerSocket to move resources from. |
|
inline |
Set the per-instance default internal buffer size used for buffered read operations.
This method updates the _defaultInternalBufferSize value, which determines the fallback buffer size used by methods like accept() or readLine() when no explicit internalBufferSize is provided.
This does not affect the kernel-level SO_RCVBUF. It applies only to the internal buffering layer used in higher-level stream-oriented reads (e.g., reading lines or strings).
size | New default buffer size in bytes for this socket/server instance. |
|
inline |
Set the default receive buffer size for accepted client sockets.
This sets the initial buffer size used when accepting new client connections. The buffer size determines how much data can be buffered for reading from the socket before the underlying receive buffer overflows.
[in] | size | New buffer size in bytes |
|
inline |
Set the default send buffer size for accepted client sockets.
This sets the initial send buffer size used when accepting new client connections. The buffer size determines how much data can be buffered for writing to the socket before the underlying send buffer overflows.
[in] | size | New send buffer size in bytes |
void Socket::setInternalBufferSize | ( | std::size_t | newLen | ) |
Sets the size of the internal read buffer used for string operations.
This method controls the size of the internal buffer used by read<std::string>() operations. This is distinct from setReceiveBufferSize(), which controls the operating system's socket buffer (SO_RCVBUF).
[in] | newLen | New size for the internal buffer in bytes |
std::bad_alloc | If memory allocation fails |
void ServerSocket::setIPv6Only | ( | bool | enable | ) |
Enable or disable IPv6-only mode for this server socket.
By default, an IPv6 socket is configured in dual-stack mode (accepts both IPv6 and IPv4 connections) on most platforms. Enabling IPv6-only mode restricts the socket to only IPv6 connections.
[in] | enable | True to enable IPv6-only mode, false to allow dual-stack. |
SocketException | if the socket is not IPv6, already bound, or on system error. |
void ServerSocket::setNonBlocking | ( | bool | nonBlocking | ) |
Set the server socket to non-blocking or blocking mode.
When in non-blocking mode, the accept() call will return immediately if no connections are pending, instead of blocking until a client connects.
This is useful for integrating the server socket into event loops or custom I/O polling systems.
[in] | nonBlocking | true to enable non-blocking mode, false for blocking (default). |
SocketException | on error. |
void Socket::setNonBlocking | ( | bool | nonBlocking | ) | const |
Set the socket to non-blocking or blocking mode.
Controls whether socket operations (connect, read, write) block until completion or return immediately. In non-blocking mode, operations return immediately with an error (usually EWOULDBLOCK/WSAEWOULDBLOCK) if they cannot be completed, allowing the application to perform other tasks while waiting.
[in] | nonBlocking | true to enable non-blocking mode, false to enable blocking mode (default). |
SocketException | If:
|
void ServerSocket::setOption | ( | int | level, |
int | optName, | ||
int | value ) |
Set a socket option for the listening server socket.
This method allows you to control low-level parameters of the listening (accepting) server socket. Because this socket is used only to accept new client connections, only certain options are meaningful here. Typical uses include:
Example: Enable port reuse (recommended for most servers):
[in] | level | Protocol level at which the option resides (e.g., SOL_SOCKET, IPPROTO_TCP) |
[in] | optName | Option name (e.g., SO_REUSEADDR, SO_RCVBUF) |
[in] | value | Integer value for the option |
SocketException | if the operation fails |
void Socket::setReceiveBufferSize | ( | std::size_t | size | ) |
Sets the socket's receive buffer size (SO_RCVBUF).
Configures the size of the operating system's receive buffer for this socket. A larger buffer can improve performance for high-bandwidth connections by allowing the system to buffer more incoming data, reducing the risk of packet loss during temporary processing delays.
[in] | size | Desired receive buffer size in bytes. The actual size allocated may be adjusted by the operating system. |
SocketException | If:
|
void ServerSocket::setReuseAddress | ( | bool | enable | ) |
Enable or disable address reuse for this server socket.
When address reuse is enabled (enable = true), the server socket can bind to a local address/port even if a previous socket on that port is still in the TIME_WAIT state. This is useful for restarting servers without waiting for old sockets to time out.
On UNIX-like systems, this sets the SO_REUSEADDR socket option. On Windows, it sets the equivalent option, SO_EXCLUSIVEADDRUSE.
[in] | enable | True to enable address reuse, false to disable (default OS behavior). |
SocketException | if setting the option fails (e.g., socket not open or system error). |
void ServerSocket::setReusePort | ( | bool | enable | ) |
Enable or disable the SO_REUSEPORT socket option.
The SO_REUSEPORT option allows multiple sockets on the same host to bind to the same port number, enabling load balancing of incoming connections across multiple processes or threads. This can dramatically improve scalability for high-performance servers (such as web servers or proxies).
If you compile or run on a platform where SO_REUSEPORT is unavailable, this method will not be present. Use conditional compilation (#ifdef SO_REUSEPORT) if you require portability.
Improper use of SO_REUSEPORT may result in complex behavior and should only be used if you fully understand its implications (e.g., distributing incoming connections evenly across processes).
[in] | enable | Set to true to enable SO_REUSEPORT, false to disable. |
SocketException | if setting the option fails. |
void Socket::setSendBufferSize | ( | std::size_t | size | ) |
Sets the socket's send buffer size (SO_SNDBUF).
Configures the size of the operating system's send buffer for this socket. A larger buffer can improve performance for high-bandwidth connections by allowing the system to buffer more outgoing data, reducing the risk of blocking during write operations when the network is temporarily congested.
[in] | size | Desired send buffer size in bytes. The actual size allocated may be adjusted by the operating system. |
SocketException | If:
|
|
inline |
Set the logical timeout (in milliseconds) for accepting client connections.
This timeout applies to methods like accept() and tryAccept(), and determines how long the server socket will wait for a client connection before timing out.
Unlike Socket::setSoTimeout(), this method does not call setsockopt() and does not affect the underlying socket descriptor. Instead, it is used internally to control the behavior of select() during accept operations.
timeoutMillis | Timeout value in milliseconds |
void Socket::setSoTimeout | ( | int | millis, |
bool | forRead = true, | ||
bool | forWrite = true ) |
Set timeout for socket send and/or receive operations.
Configures timeouts for socket operations, allowing fine-grained control over how long the socket will wait during blocking send or receive operations before failing. This provides an alternative to non-blocking mode for handling slow or unresponsive peers.
[in] | millis | Timeout duration in milliseconds:
|
[in] | forRead | If true, set receive timeout (default: true) |
[in] | forWrite | If true, set send timeout (default: true) |
SocketException | If:
|
void Socket::shutdown | ( | ShutdownMode | how | ) | const |
Shutdown specific communication aspects of the socket.
This method allows for a controlled shutdown of socket communications in one or both directions without closing the socket itself. Unlike close(), which immediately terminates all communications, shutdown() provides finer control over how the connection is terminated.
[in] | how | Specifies which operations to shut down:
|
SocketException | If: |
|
delete |
Default constructor (deleted) for Socket class.
The default constructor is explicitly deleted to prevent the creation of uninitialized Socket objects. Each socket must be explicitly constructed with a valid host/port combination or from an accepted client connection.
|
delete |
Copy constructor (deleted) for Socket class.
This constructor is explicitly deleted because Socket objects manage unique system resources (socket file descriptors) that cannot be safely duplicated. Each socket must have exclusive ownership of its underlying resources to prevent issues like:
Instead of copying, use move semantics (Socket&&) to transfer ownership of a Socket from one object to another. For example:
[in] | rhs | The Socket object to copy from (unused since deleted) |
|
inlinenoexcept |
Move constructor that transfers ownership of socket resources.
Creates a new Socket by taking ownership of another Socket's resources. This constructor is essential for scenarios where Socket objects need to be transferred (e.g., returning from functions, storing in containers) since copying is disabled.
The constructor performs the following:
The moved-from socket (rhs) remains valid but will be in a default-constructed state with no active connection (_sockFd = INVALID_SOCKET).
[in,out] | rhs | The Socket object to move from. After the move, rhs will be left in a valid but disconnected state. |
|
protected |
Protected constructor used internally to create Socket objects for accepted client connections.
This constructor is specifically designed to be called by ServerSocket::accept() and related methods to create Socket instances representing established client connections. It initializes a Socket using an already-connected socket descriptor and the peer's address, and configures internal buffers and socket options for subsequent I/O.
[in] | client | Socket descriptor obtained from a successful accept() call. |
[in] | addr | Remote peer address (sockaddr_storage for IPv4/IPv6 compatibility). |
[in] | len | Size of the peer address structure (sockaddr_in, sockaddr_in6, etc.). |
[in] | recvBufferSize | Size in bytes for the internal receive buffer and the socket's SO_RCVBUF. |
[in] | sendBufferSize | Size in bytes for the socket's SO_SNDBUF buffer. |
[in] | internalBufferSize | Size of the internal buffering layer used for string-based and stream reads. |
SocketException | If the socket options cannot be set or internal buffer allocation fails. |
Socket::Socket | ( | std::string_view | host, |
Port | port, | ||
std::optional< std::size_t > | recvBufferSize = std::nullopt, | ||
std::optional< std::size_t > | sendBufferSize = std::nullopt, | ||
std::optional< std::size_t > | internalBufferSize = std::nullopt ) |
Creates a new Socket object configured to connect to the specified host and port.
This constructor initializes a Socket object for a TCP connection to a remote host. It performs hostname resolution using getaddrinfo() to support both IPv4 and IPv6 addresses, creates the socket, and configures internal and socket-level buffer sizes.
Note: This constructor does not establish a network connection. You must explicitly call connect() after construction to initiate the TCP handshake.
[in] | host | The remote hostname or IP address (e.g., "example.com", "127.0.0.1", "::1"). |
[in] | port | The TCP port number to connect to (range: 1–65535). |
[in] | recvBufferSize | Socket-level receive buffer size (SO_RCVBUF). Defaults to DefaultBufferSize (4096 bytes). |
[in] | sendBufferSize | Socket-level send buffer size (SO_SNDBUF). Defaults to DefaultBufferSize (4096 bytes). |
[in] | internalBufferSize | Size of the internal buffer used for high-level read<T>() operations. This is distinct from the kernel socket buffers. Defaults to `DefaultBufferSize (4096 bytes). |
SocketException | If hostname resolution fails, socket creation fails, or buffer configuration fails. |
|
nodiscard |
Attempt to accept an incoming client connection, waiting up to a specified timeout.
This method waits for an incoming client connection using the provided timeoutMillis value, overriding any global timeout set with setSoTimeout(). If timeoutMillis is negative, the method blocks indefinitely until a client connects. If timeoutMillis is zero, the method polls and returns immediately if no client is waiting.
Unlike accept(int timeoutMillis, ...), which throws a SocketTimeoutException if the timeout expires, this method returns std::nullopt in that case. This makes it ideal for polling loops or event-driven servers.
Internally, this method uses waitReady(timeoutMillis) (via select()) to check for connection readiness. If the socket is ready, acceptBlocking(...) is called to retrieve the connection. Otherwise, std::nullopt is returned.
The blocking or non-blocking mode of the server socket (via setNonBlocking(true)) does not affect the behavior of this method. Readiness is determined exclusively via select(). However, due to inherent race conditions in all socket APIs, it’s still possible for accept() to fail with EWOULDBLOCK or EAGAIN after readiness has been reported. In such cases, a SocketException is thrown.
[in] | timeoutMillis | Timeout in milliseconds to wait for a client connection:
|
[in] | recvBufferSize | The receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize(). |
[in] | sendBufferSize | The send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize(). |
[in] | internalBufferSize | The internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize(). |
SocketException | if the server socket is invalid, closed, or an internal error occurs. |
|
nodiscard |
Attempt to accept an incoming client connection, returning immediately or after the configured timeout.
This method waits for an incoming client connection using the timeout set by setSoTimeout(). If no timeout is configured (i.e., negative value), the method blocks indefinitely until a client connects. If the timeout is zero, the method polls and returns immediately if no client is waiting.
Unlike accept(), this method does not throw a SocketTimeoutException if no client is available. Instead, it returns std::nullopt. This makes it suitable for event loops or non-blocking server designs.
Internally, this method uses waitReady() (which uses select()) to check for pending connections. If a client is ready, acceptBlocking() is called to retrieve the connection. If not, std::nullopt is returned.
The blocking or non-blocking mode of the server socket (via setNonBlocking()) does not affect the waiting behavior of this method, since select() is used for readiness. In rare cases, accept() may still fail with EWOULDBLOCK or EAGAIN if the connection is lost between readiness check and accept call, in which case a SocketException is thrown.
[in] | recvBufferSize | The receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize(). |
[in] | sendBufferSize | The send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize(). |
[in] | internalBufferSize | The internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize(). |
SocketException | if the server socket is not initialized, closed, or if an internal error occurs. |
|
nodiscard |
Wait for the server socket to become ready to accept an incoming connection.
This method blocks until the server socket is ready to accept a new client connection, using an optional timeout. It is used internally by accept() and tryAccept(), and can also be used directly in custom wait loops.
This method is thread-safe as long as the server socket is not concurrently closed or modified.
[in] | timeoutMillis | Optional timeout in milliseconds. Defaults to the value set by setSoTimeout(). |
SocketException | if the socket is uninitialized or if a system error occurs during readiness check. |
|
nodiscard |
Writes data to the socket, handling partial writes.
Attempts to write the provided string data to the connected socket. This method may perform a partial write, meaning not all data may be sent in a single call. The return value indicates exactly how many bytes were successfully written.
[in] | message | The string data to send. Can contain binary data (including null bytes). |
SocketException | If:
|
size_t Socket::writeAll | ( | std::string_view | message | ) | const |
Writes the entire contents of a message to the socket, handling partial writes.
Ensures that the complete message is transmitted by handling partial writes and retrying until all data is sent or an error occurs. This method is particularly useful when dealing with large messages that may require multiple write operations.
[in] | message | The data to send. Can contain binary data (including null bytes). |
SocketException | If:
|
std::size_t Socket::writeAtMostWithTimeout | ( | std::string_view | data, |
int | timeoutMillis ) const |
Performs a best-effort write with a total timeout.
Waits up to timeoutMillis for the socket to become writable, then attempts a single send() of up to data.size() bytes. This method does not retry. It is suitable for time-sensitive or polling-based write loops.
data | The data to send. |
timeoutMillis | The maximum time to wait before sending. |
SocketException | If:
|
std::size_t Socket::writeFrom | ( | const void * | data, |
std::size_t | len ) const |
Writes up to len bytes from a raw memory buffer in a single send call.
This method sends data directly from a raw memory pointer using a best-effort write. It may write fewer bytes than requested, depending on socket buffer availability. It is the low-level counterpart to write(std::string_view) and avoids constructing or copying into strings.
data | Pointer to the memory to write. |
len | Number of bytes to send. |
SocketException | If:
|
std::size_t Socket::writeFromAll | ( | const void * | data, |
std::size_t | len ) const |
Writes all bytes from a raw memory buffer, retrying until complete.
This method repeatedly calls send() until the full len bytes of the buffer are successfully transmitted. It guarantees that all bytes are written, or throws an exception on failure. This is the raw-buffer equivalent of writeAll().
data | Pointer to the binary buffer to send. |
len | Number of bytes to transmit. |
SocketException | If:
|
|
inline |
Writes a length-prefixed payload using a fixed-size prefix type.
Sends a message that consists of a length prefix followed by the actual payload. The prefix type T determines the format and size of the length field and is written in network byte order for cross-platform interoperability.
+----------------+----------------------+ | Length (T) | Payload (n bytes) | +----------------+----------------------+ |<- sizeof(T) ->|<---- length ------->|
T | The unsigned integral type used for the length prefix (e.g., uint32_t). Must be a trivially copyable type. |
payload | The string data to send. The length of this string will be encoded as the prefix and must not exceed the maximum value of type T. |
SocketException | If:
|
|
inline |
Writes a binary payload prefixed with its length using a fixed-size integer type.
Sends a length-prefixed binary message, where the prefix is a fixed-size integral type T followed by a raw binary buffer. This version avoids constructing a temporary std::string, making it efficient for zero-copy binary protocols and high-performance I/O paths.
+----------------+----------------------+ | Length (T) | Payload (n bytes) | +----------------+----------------------+ |<- sizeof(T) ->|<---- len --------->|
T | The unsigned integral type used for the length prefix (e.g., uint32_t). Must be a trivially copyable type. |
data | Pointer to the binary payload data. |
len | Number of bytes to write from data. |
SocketException | If:
|
std::size_t Socket::writev | ( | std::span< const std::string_view > | buffers | ) | const |
Writes multiple buffers in a single system call using scatter/gather I/O.
This method efficiently writes multiple non-contiguous buffers to the socket using platform-specific vectorized I/O calls. It is ideal for sending structured packets, headers + body, or other segmented data without concatenating them.
buffers | A span of string views to send as a scatter/gather I/O batch. |
SocketException | If:
|
std::size_t Socket::writevAll | ( | std::span< const std::string_view > | buffers | ) | const |
Writes all buffers fully using vectorized I/O with automatic retry on partial sends.
Ensures that the entire contents of all buffers in the given span are fully transmitted, retrying as needed. This is the guaranteed-delivery counterpart to writev().
buffers | A span of string fragments to send as a contiguous logical payload. |
SocketException | If:
|
std::size_t Socket::writevFrom | ( | std::span< const BufferView > | buffers | ) | const |
Writes multiple raw memory regions using vectorized I/O.
Sends the contents of all buffers in the given span using scatter/gather I/O. This performs a single system call (writev() on POSIX, WSASend() on Windows), and may transmit fewer bytes than requested. Use writevFromAll() for full delivery.
buffers | A span of BufferView elements (data + size). |
SocketException | If:
|
std::size_t Socket::writevFromAll | ( | std::span< BufferView > | buffers | ) | const |
Writes all raw memory regions fully using scatter/gather I/O.
This method guarantees full delivery of all bytes across the given buffer span. Internally retries writevFrom() until every buffer is fully written. This is the binary-safe, zero-copy equivalent of writevAll().
buffers | A span of raw buffers to send completely. |
SocketException | If:
|
std::size_t Socket::writevFromWithTotalTimeout | ( | std::span< BufferView > | buffers, |
int | timeoutMillis ) const |
Writes all raw memory buffers fully within a timeout using scatter I/O.
Sends multiple binary buffers using scatter/gather I/O, retrying as needed to ensure that all bytes are delivered within the specified timeout window. Fails if not all buffers can be sent before the timeout expires.
buffers | A span of raw memory buffers to fully write. |
timeoutMillis | Total timeout in milliseconds across all retries. |
SocketException | If:
|
std::size_t Socket::writevWithTotalTimeout | ( | std::span< const std::string_view > | buffers, |
int | timeoutMillis ) const |
Writes all buffers fully within a total timeout using vectorized I/O.
Sends the contents of all buffers in the given span using scatter/gather I/O. Retries on partial sends until either all buffers are sent or the timeout expires. This is the timeout-aware counterpart to writevAll().
buffers | A span of buffers to send in order. |
timeoutMillis | Maximum total time allowed for the operation, in milliseconds. |
SocketException | If:
|
std::size_t Socket::writeWithTotalTimeout | ( | std::string_view | data, |
int | timeoutMillis ) const |
Writes the full payload with a total timeout across all retries.
Repeatedly attempts to write all bytes from data, retrying partial writes as needed. The entire operation must complete within timeoutMillis milliseconds. If the timeout expires before all data is sent, the method throws a SocketException.
data | The data to send. |
timeoutMillis | Maximum total duration (in milliseconds) to complete the operation. |
SocketException | If:
|
|
noexcept |
Destructor that automatically closes the server socket and releases all associated resources.
This destructor ensures proper cleanup of system resources when a ServerSocket object is destroyed:
The destructor is marked noexcept to prevent exception propagation during stack unwinding, as per C++ best practices. Any errors that occur during cleanup are logged but not thrown.
|
noexcept |
Destructs the Socket object, closing connections and freeing resources.
This destructor ensures proper cleanup of all resources owned by the Socket:
The destructor is marked noexcept to prevent exception propagation during stack unwinding, as per C++ best practices. Any errors that occur during cleanup (e.g., socket closure failures) are ignored.