jsocketpp 1.0
A cross-platform C++20 socket library.
Loading...
Searching...
No Matches

Classes and functions for TCP networking. More...

Collaboration diagram for TCP Sockets:

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 ()=delete
 Default constructor (deleted) for ServerSocket class.
 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.
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).
ServerSocketjsocketpp::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.
ServerSocketjsocketpp::ServerSocket::operator= (ServerSocket &&rhs) noexcept
 Move assignment operator for ServerSocket.
 jsocketpp::ServerSocket::~ServerSocket () noexcept override
 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, int soRecvTimeoutMillis=-1, int soSendTimeoutMillis=-1, bool tcpNoDelay=true, bool keepAlive=false, bool nonBlocking=false) const
 Accept an incoming client connection, respecting the configured socket timeout and applying tuning options.
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, int soRecvTimeoutMillis=-1, int soSendTimeoutMillis=-1, bool tcpNoDelay=true, bool keepAlive=false, bool nonBlocking=false) const
 Accept an incoming client connection, waiting up to the specified timeout and applying socket tuning options.
std::optional< Socketjsocketpp::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, int soRecvTimeoutMillis=-1, int soSendTimeoutMillis=-1, bool tcpNoDelay=true, bool keepAlive=false, bool nonBlocking=false) const
 Attempt to accept an incoming client connection, returning std::nullopt on timeout instead of throwing.
std::optional< Socketjsocketpp::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, int soRecvTimeoutMillis=-1, int soSendTimeoutMillis=-1, bool tcpNoDelay=true, bool keepAlive=false, bool nonBlocking=false) const
 Attempt to accept an incoming client connection, waiting up to a specified timeout and returning std::nullopt on 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, int soRecvTimeoutMillis=-1, int soSendTimeoutMillis=-1, bool tcpNoDelay=true, bool keepAlive=false, bool nonBlocking=false) const
 Accepts a TCP client connection, configures the socket, and returns a high-level Socket object.
std::optional< Socketjsocketpp::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, int soRecvTimeoutMillis=-1, int soSendTimeoutMillis=-1, bool tcpNoDelay=true, bool keepAlive=false, bool nonBlocking=false) const
 Attempts to accept a client connection in non-blocking mode and returns a fully configured Socket.
std::future< Socketjsocketpp::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, int soRecvTimeoutMillis=-1, int soSendTimeoutMillis=-1, bool tcpNoDelay=true, bool keepAlive=false, bool nonBlocking=false) const
 Asynchronously accept an incoming client connection, returning a std::future that resolves to a configured Socket.
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, int soRecvTimeoutMillis=-1, int soSendTimeoutMillis=-1, bool tcpNoDelay=true, bool keepAlive=false, bool nonBlocking=false) const
 Asynchronously accept a client connection and invoke a callback upon completion or error.
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.
bool jsocketpp::ServerSocket::waitReady (std::optional< int > timeoutMillis=std::nullopt) const
 Waits for the server socket to become ready to accept an incoming connection.
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::cleanup ()
 Cleans up internal resources and resets the server socket state.
void jsocketpp::ServerSocket::cleanupAndThrow (int errorCode)
 Cleans up internal resources and throws a SocketException.
void jsocketpp::ServerSocket::cleanupAndRethrow ()
 Cleans up internal resources and rethrows the current exception.
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 (const 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=DefaultBufferSize, std::size_t sendBufferSize=DefaultBufferSize, std::size_t internalBufferSize=DefaultBufferSize, int soRecvTimeoutMillis=-1, int soSendTimeoutMillis=-1, bool tcpNoDelay=true, bool keepAlive=false, bool nonBlocking=false)
 Wraps an accepted TCP client socket with optional tuning parameters.
 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, bool reuseAddress=true, int soRecvTimeoutMillis=-1, int soSendTimeoutMillis=-1, bool dualStack=true, bool tcpNoDelay=true, bool keepAlive=false, bool nonBlocking=false, bool autoConnect=true, bool autoBind=false, std::string_view localAddress="", Port localPort=0)
 Constructs a TCP client socket, resolves the remote host and port, and optionally binds or connects.
 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.
Socketjsocketpp::Socket::operator= (const Socket &rhs)=delete
 Copy assignment operator (deleted) for Socket class.
Socketjsocketpp::Socket::operator= (Socket &&rhs) noexcept
 Move assignment operator that transfers socket ownership safely.
 jsocketpp::Socket::~Socket () noexcept override
 Destructs the Socket object, closing connections and freeing resources.
void jsocketpp::Socket::bind (std::string_view localHost, Port port)
 Binds the client socket to a specific local IP address and/or port.
void jsocketpp::Socket::bind (Port port)
 Binds the client socket to all interfaces (INADDR_ANY) using the specified port.
void jsocketpp::Socket::bind ()
 Binds the client socket to all interfaces using an ephemeral port.
bool jsocketpp::Socket::isBound () const noexcept
 Indicates whether the socket has been explicitly bound to a local address and/or port.
bool jsocketpp::Socket::isConnected () const noexcept
 Indicates whether the socket has been successfully connected to a remote host.
std::string jsocketpp::Socket::getLocalIp (bool convertIPv4Mapped=true) const
 Retrieves the local IP address this socket is bound to.
Port jsocketpp::Socket::getLocalPort () const
 Retrieves the local port number this socket is bound to.
std::string jsocketpp::Socket::getLocalSocketAddress (bool convertIPv4Mapped=true) const
 Retrieves the full local socket address in the form "IP:port".
std::string jsocketpp::Socket::getRemoteIp (bool convertIPv4Mapped=true) const
 Retrieves the IP address of the remote peer this TCP socket is connected to.
Port jsocketpp::Socket::getRemotePort () const
 Retrieves the port number of the remote peer this TCP socket is connected to.
std::string jsocketpp::Socket::getRemoteSocketAddress (bool convertIPv4Mapped=true) const
 Get the connected peer's socket address as a formatted string.
void jsocketpp::Socket::connect (int timeoutMillis=-1)
 Establishes a TCP connection to the remote host with optional timeout control.
template<typename T>
jsocketpp::Socket::read ()
 Reads a fixed-size, trivially copyable object of type T from the socket.
std::string jsocketpp::Socket::readExact (std::size_t n) const
 Reads exactly n bytes from the socket into a std::string.
std::string jsocketpp::Socket::readUntil (char delimiter, std::size_t maxLen=8192, bool includeDelimiter=true)
 Reads data from the socket until a specified delimiter character is encountered.
std::string jsocketpp::Socket::readLine (const std::size_t maxLen=8192, const bool includeDelimiter=true)
 Reads a line terminated by '
' from the socket.
std::string jsocketpp::Socket::readAtMost (std::size_t n) const
 Performs a single best-effort read of up to n bytes from the socket.
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
 Attempts a best-effort read of up to n bytes with a timeout constraint.
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.
std::size_t jsocketpp::Socket::write (std::string_view message) const
 Sends data to the socket using a single, best-effort write operation.
std::size_t jsocketpp::Socket::writeAll (std::string_view message) const
 Writes the entire contents of a message to the socket, retrying as needed.
template<typename T>
std::size_t jsocketpp::Socket::writePrefixed (const std::string_view payload)
 Writes a length-prefixed payload using a fixed-size integral prefix.
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::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.
bool jsocketpp::Socket::waitReady (bool forWrite, int timeoutMillis) const
 Waits for the socket to become ready for reading or writing.
bool jsocketpp::Socket::isClosed () const noexcept
 Reports whether the socket has been closed or invalidated.
bool jsocketpp::Socket::isInputShutdown () const noexcept
 Checks whether the socket's input stream has been shutdown.
bool jsocketpp::Socket::isOutputShutdown () const noexcept
 Checks whether the socket's output stream has been shutdown.
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::cleanup ()
 Internal helper that closes the socket and clears address resolution state.
void jsocketpp::Socket::cleanupAndThrow (int errorCode)
 Closes the socket, resets internal state, and throws a SocketException.
void jsocketpp::Socket::cleanupAndRethrow ()
 Cleans up socket resources and rethrows the currently active exception.
void jsocketpp::Socket::resetShutdownFlags () noexcept
 Resets internal shutdown state flags to false.
template<>
std::string jsocketpp::Socket::read ()
 Specialization of read<T>() for reading a single buffer of string data.

Friends

class jsocketpp::Socket::ServerSocket
 Grants ServerSocket access to private members.

Detailed Description

Classes and functions for TCP networking.

Function Documentation

◆ accept() [1/2]

Socket 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,
int soRecvTimeoutMillis = -1,
int soSendTimeoutMillis = -1,
bool tcpNoDelay = true,
bool keepAlive = false,
bool nonBlocking = false ) const
nodiscard

Accept an incoming client connection, waiting up to the specified timeout and applying socket tuning options.

This method waits for a client connection using the specified timeout (in milliseconds), then calls the underlying system accept() and returns a fully configured Socket object.


⏱ Timeout Behavior

  • If timeoutMillis is negative, the method blocks indefinitely.
  • If timeoutMillis is zero, the method polls once and returns immediately if no client is waiting.
  • If timeoutMillis is positive, the method waits up to that many milliseconds before throwing a SocketTimeoutException if no connection is made.

Internally, this method uses waitReady(timeoutMillis) (based on select()) to wait for readiness and then calls acceptBlocking() with the resolved parameters.


⚙️ Configuration of Accepted Socket

The returned Socket will be configured with the following tuning options:

  • recvBufferSize, sendBufferSize: OS-level buffer sizes (SO_RCVBUF, SO_SNDBUF)
  • internalBufferSize: Internal buffer for high-level read() operations
  • soRecvTimeoutMillis: Socket-level receive timeout (SO_RCVTIMEO) in milliseconds
  • soSendTimeoutMillis: Socket-level send timeout (SO_SNDTIMEO) in milliseconds
  • tcpNoDelay: Disables Nagle’s algorithm for latency-sensitive connections (default: true)
  • keepAlive: Enables TCP keep-alive (SO_KEEPALIVE)
  • nonBlocking: Immediately sets the accepted socket to non-blocking mode

⚠️ Thread Safety

This method is not thread-safe. Concurrent calls to accept(), acceptBlocking(), or acceptNonBlocking() from multiple threads or processes may lead to race conditions. Synchronize access to the ServerSocket if needed.


🧠 Example

ServerSocket server(8080);
server.bind();
server.listen();
try {
Socket client = server.accept(2000, // Wait up to 2 seconds
8192, 8192, 8192, // Buffer sizes
3000, 1000, // Timeouts
true, true, false // TCP_NODELAY, keepAlive, nonBlocking
);
handleClient(client);
} catch (const SocketTimeoutException&) {
std::cout << "No client connected within timeout." << std::endl;
}
Exception class for socket operations that time out.
Definition SocketTimeoutException.hpp:39
TCP client connection abstraction (Java-like interface).
Definition Socket.hpp:93
ServerSocket()=delete
Default constructor (deleted) for ServerSocket class.

Parameters
[in]timeoutMillisTimeout in milliseconds to wait for a connection:
  • Negative: block indefinitely
  • Zero: poll once and return immediately
  • Positive: wait up to this many milliseconds
[in]recvBufferSizeOptional socket receive buffer size (SO_RCVBUF)
[in]sendBufferSizeOptional socket send buffer size (SO_SNDBUF)
[in]internalBufferSizeInternal buffer used by read() and read<T>()
[in]soRecvTimeoutMillisReceive timeout in milliseconds (SO_RCVTIMEO); -1 disables
[in]soSendTimeoutMillisSend timeout in milliseconds (SO_SNDTIMEO); -1 disables
[in]tcpNoDelayWhether to disable Nagle’s algorithm (TCP_NODELAY); default: true
[in]keepAliveWhether to enable TCP keep-alive (SO_KEEPALIVE)
[in]nonBlockingWhether to set the accepted socket to non-blocking mode
Returns
A configured Socket representing the connected client
Exceptions
SocketExceptionIf:
SocketTimeoutExceptionIf no client connects before the timeout expires
Precondition
Server socket must be valid, bound, and listening
Postcondition
Returns a connected Socket or throws an exception on failure
See also
accept(), tryAccept(), acceptBlocking(), setSoTimeout(), waitReady()

◆ accept() [2/2]

Socket 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,
int soRecvTimeoutMillis = -1,
int soSendTimeoutMillis = -1,
bool tcpNoDelay = true,
bool keepAlive = false,
bool nonBlocking = false ) const
nodiscard

Accept an incoming client connection, respecting the configured socket timeout and applying tuning options.

This method waits for an incoming connection using the timeout set via setSoTimeout() or getSoTimeout(). Once a connection is ready, it calls the underlying system accept() and returns a fully configured Socket object with the specified buffer sizes, timeouts, and TCP socket options.


⏱ Timeout Behavior

  • If the timeout is negative (default), the method blocks indefinitely.
  • If the timeout is zero, it polls once and returns immediately if no client is waiting.
  • If the timeout is positive, it waits for the given number of milliseconds before throwing a SocketTimeoutException if no connection occurs.

Internally, this method uses select() via waitReady() to wait for readiness, then invokes accept(). The socket’s blocking mode (via setNonBlocking()) does not affect this method.


⚙️ Configuration of Accepted Socket

The returned Socket is configured immediately using the provided tuning parameters:

  • recvBufferSize, sendBufferSize: OS-level socket buffers (SO_RCVBUF, SO_SNDBUF)
  • internalBufferSize: Internal buffer used by read<T>() and read<std::string>()
  • soRecvTimeoutMillis: Read timeout in milliseconds (SO_RCVTIMEO); -1 disables
  • soSendTimeoutMillis: Send timeout in milliseconds (SO_SNDTIMEO); -1 disables
  • tcpNoDelay: Disables Nagle’s algorithm for low-latency communication (default: true)
  • keepAlive: Enables TCP keep-alive probes
  • nonBlocking: If true, the accepted socket is set to non-blocking mode

⚠️ Thread Safety

This method is not thread-safe. Concurrent calls to accept() or acceptNonBlocking() from multiple threads or processes may cause race conditions or undefined behavior. Protect the ServerSocket instance with a mutex if needed.


🧠 Example

ServerSocket server(8080);
server.bind();
server.listen();
server.setSoTimeout(5000); // 5-second accept timeout
try {
Socket client = server.accept(
8192, 8192, 8192,
3000, 1000,
true, true, false);
handleClient(client);
} catch (const SocketTimeoutException&) {
// No client connected within 5 seconds
}

Parameters
[in]recvBufferSizeOptional socket receive buffer size (SO_RCVBUF)
[in]sendBufferSizeOptional socket send buffer size (SO_SNDBUF)
[in]internalBufferSizeOptional internal buffer size for high-level reads
[in]soRecvTimeoutMillisRead timeout (SO_RCVTIMEO) in milliseconds; -1 disables
[in]soSendTimeoutMillisSend timeout (SO_SNDTIMEO) in milliseconds; -1 disables
[in]tcpNoDelayWhether to disable Nagle's algorithm (TCP_NODELAY); default: true
[in]keepAliveWhether to enable TCP keep-alive probes (SO_KEEPALIVE)
[in]nonBlockingWhether to set the accepted socket to non-blocking mode
Returns
A fully configured Socket representing the connected client
Exceptions
SocketExceptionIf:
  • The server socket is invalid, closed, or in an incorrect state
  • accept() fails due to a system error
  • Socket configuration fails after acceptance
SocketTimeoutExceptionIf the timeout expires with no connection
Precondition
The server socket must be valid, bound, and listening
Postcondition
A connected and configured Socket is returned on success
See also
setSoTimeout(), getSoTimeout(), waitReady(), acceptBlocking(), acceptNonBlocking()

◆ acceptAsync() [1/2]

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,
int soRecvTimeoutMillis = -1,
int soSendTimeoutMillis = -1,
bool tcpNoDelay = true,
bool keepAlive = false,
bool nonBlocking = false ) const

Asynchronously accept a client connection and invoke a callback upon completion or error.

This method starts a detached background thread that performs a socket accept() and invokes a user-provided callback upon completion. It is designed for event-driven or callback-oriented architectures where blocking or polling is not desirable.


⚙️ Behavior

  • Accepts one client connection in a background thread
  • Applies the same tuning options available to synchronous accept() methods
  • If a client connects, the callback receives a fully constructed Socket and nullptr exception
  • If an error occurs, the callback receives std::nullopt and a std::exception_ptr
  • You may rethrow the exception in the callback using std::rethrow_exception()

🔁 Callback Signature

void callback(std::optional<Socket>, std::exception_ptr);

⚠️ Thread Safety

This method is not thread-safe. Do not call accept(), acceptAsync(), or related methods concurrently on the same ServerSocket unless access is externally synchronized.


⚠️ Lifetime Warning

The ServerSocket must outlive the background thread and callback execution. Destroying the ServerSocket before the callback is invoked results in undefined behavior.


⚙️ Configuration of Accepted Socket

The Socket passed to the callback (if any) will be configured using:

  • recvBufferSize, sendBufferSize: OS-level buffer sizes (SO_RCVBUF, SO_SNDBUF)
  • internalBufferSize: Internal buffer used by read<T>() and read<std::string>()
  • soRecvTimeoutMillis: Socket receive timeout (SO_RCVTIMEO) in milliseconds
  • soSendTimeoutMillis: Socket send timeout (SO_SNDTIMEO) in milliseconds
  • tcpNoDelay: Disables Nagle’s algorithm (TCP_NODELAY) (default: true)
  • keepAlive: Enables TCP keep-alive (SO_KEEPALIVE)
  • nonBlocking: Immediately sets the accepted socket to non-blocking mode

🧠 Example

server.acceptAsync(
[](std::optional<Socket> clientOpt, std::exception_ptr eptr) {
if (eptr) {
try { std::rethrow_exception(eptr); }
catch (const SocketException& ex) {
std::cerr << "Accept failed: " << ex.what() << std::endl;
}
} else if (clientOpt) {
std::cout << "Accepted client from: "
<< clientOpt->getRemoteSocketAddress() << std::endl;
// Handle client...
}
},
8192, 4096, 8192, 3000, 1000, true, true, false
);
Represents socket-related errors in the jsocketpp library.
Definition SocketException.hpp:63

Parameters
[in]callbackCompletion handler that receives the accepted socket or an exception
[in]recvBufferSizeOptional receive buffer size (SO_RCVBUF)
[in]sendBufferSizeOptional send buffer size (SO_SNDBUF)
[in]internalBufferSizeOptional internal buffer for read<T>()
[in]soRecvTimeoutMillisReceive timeout (SO_RCVTIMEO) in milliseconds; -1 disables
[in]soSendTimeoutMillisSend timeout (SO_SNDTIMEO) in milliseconds; -1 disables
[in]tcpNoDelayWhether to disable Nagle’s algorithm (TCP_NODELAY); default: true
[in]keepAliveWhether to enable TCP keep-alive (SO_KEEPALIVE)
[in]nonBlockingWhether to immediately make the accepted socket non-blocking
Precondition
The server socket must be valid, bound, and listening
Postcondition
The callback is invoked exactly once, either with a valid Socket or an error
See also
accept(), tryAccept(), acceptBlocking(), acceptAsync(std::future)
std::optional, std::exception_ptr, std::rethrow_exception

◆ acceptAsync() [2/2]

std::future< Socket > 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,
int soRecvTimeoutMillis = -1,
int soSendTimeoutMillis = -1,
bool tcpNoDelay = true,
bool keepAlive = false,
bool nonBlocking = false ) const
nodiscard

Asynchronously accept an incoming client connection, returning a std::future that resolves to a configured Socket.

This method initiates an asynchronous accept operation on the server socket using std::async(std::launch::async, ...). It returns a std::future<Socket> that will become ready once a client is accepted or an error/timeout occurs.


⚙️ Behavior

  • The calling thread is never blocked
  • A background thread calls accept(...) with the specified tuning options
  • When .get() is called on the future:

This function is ideal for use in thread-based architectures where the server must continue operating while waiting for new clients in parallel.


⚠️ Thread Safety

This method is not thread-safe. You must externally synchronize calls to acceptAsync(), accept(), tryAccept(), and related methods on the same ServerSocket instance.


⚠️ Lifetime Warning

The ServerSocket object must remain valid and alive at least until the returned std::future has resolved and .get() has been called. Using this method in contexts where the ServerSocket may be destroyed early can lead to undefined behavior or dangling references.


⚙️ Configuration of Accepted Socket

The returned Socket (from .get()) will be initialized with:

  • recvBufferSize, sendBufferSize: OS-level buffer sizes (SO_RCVBUF, SO_SNDBUF)
  • internalBufferSize: High-level internal buffer used for read() / read<T>()
  • soRecvTimeoutMillis: Socket read timeout in milliseconds (SO_RCVTIMEO)
  • soSendTimeoutMillis: Socket send timeout in milliseconds (SO_SNDTIMEO)
  • tcpNoDelay: Disables Nagle’s algorithm for lower latency (default: true)
  • keepAlive: Enables TCP keep-alive (SO_KEEPALIVE)
  • nonBlocking: If true, sets the accepted socket to non-blocking mode

🧠 Example

ServerSocket server(8080);
server.bind();
server.listen();
std::future<Socket> future = server.acceptAsync(
8192, 8192, 8192, // buffer sizes
3000, 1000, // socket timeouts
true, true, false // TCP_NODELAY, keep-alive, non-blocking
);
// Do other work...
if (future.wait_for(std::chrono::seconds(5)) == std::future_status::ready) {
Socket client = future.get(); // May throw
handleClient(client);
} else {
std::cout << "Still waiting or timed out." << std::endl;
}

Parameters
[in]recvBufferSizeOptional socket receive buffer size (SO_RCVBUF)
[in]sendBufferSizeOptional socket send buffer size (SO_SNDBUF)
[in]internalBufferSizeOptional internal buffer size for read<T>() operations
[in]soRecvTimeoutMillisSocket receive timeout (SO_RCVTIMEO) in milliseconds; -1 disables
[in]soSendTimeoutMillisSocket send timeout (SO_SNDTIMEO) in milliseconds; -1 disables
[in]tcpNoDelayWhether to disable Nagle’s algorithm (TCP_NODELAY); default: true
[in]keepAliveWhether to enable TCP keep-alive (SO_KEEPALIVE)
[in]nonBlockingWhether to immediately set the accepted socket to non-blocking mode
Returns
A std::future<Socket> that resolves to a connected and configured client socket, or throws on error
Exceptions
SocketExceptionIf a fatal socket error occurs during background accept
SocketTimeoutExceptionIf no client connects and the configured timeout expires
Precondition
Server socket must be valid, bound, and listening
Postcondition
Future resolves to a connected Socket, or throws from .get()
See also
accept(), acceptBlocking(), tryAccept(), acceptNonBlocking(), acceptAsync(callback), std::future, std::async

◆ acceptBlocking()

Socket 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,
int soRecvTimeoutMillis = -1,
int soSendTimeoutMillis = -1,
bool tcpNoDelay = true,
bool keepAlive = false,
bool nonBlocking = false ) const
nodiscard

Accepts a TCP client connection, configures the socket, and returns a high-level Socket object.

This method calls the underlying system accept() on the listening server socket.

  • If the socket is in blocking mode (default), this method blocks until a client connects.
  • If the socket is in non-blocking mode, it returns immediately:
    • If a client is pending, it returns a configured Socket.
    • If no client is waiting, it throws SocketException with EWOULDBLOCK or EAGAIN.

⚙️ Behavior

  • Applies OS-level buffer sizes (SO_RCVBUF, SO_SNDBUF) to the accepted socket
  • Applies high-level internalBufferSize for read<T>()
  • Configures optional timeouts for send and receive operations
  • Enables/disables TCP features like Nagle’s algorithm and keep-alive
  • Sets blocking mode immediately after accept if requested

🧪 Comparison with acceptNonBlocking()

  • Both methods rely on the socket’s current blocking mode
  • acceptBlocking() always throws on failure, including EWOULDBLOCK
  • acceptNonBlocking() is used in polling loops where no connection is not an error

⚠️ Thread Safety

This method is not thread-safe. Simultaneous accept() calls on the same ServerSocket from multiple threads may result in race conditions or inconsistent results.


🧠 Example

ServerSocket server(8080);
server.bind();
server.listen();
// Blocking pattern
Socket client = server.acceptBlocking(8192, 8192, 8192,
3000, 1000, // timeouts
true, true, false);
// Non-blocking pattern
server.setNonBlocking(true);
try {
Socket client = server.acceptBlocking(); // may throw EWOULDBLOCK
// handle client
} catch (const SocketException& ex) {
if (ex.code() == EWOULDBLOCK) {
// no connection available yet
} else {
throw;
}
}
void setNonBlocking(bool nonBlocking)
Enables or disables non-blocking mode on the socket.
Definition SocketOptions.cpp:223

Parameters
[in]recvBufferSizeOptional socket receive buffer size (SO_RCVBUF)
[in]sendBufferSizeOptional socket send buffer size (SO_SNDBUF)
[in]internalBufferSizeInternal buffer used by read<T>() and read<std::string>()
[in]soRecvTimeoutMillisReceive timeout (SO_RCVTIMEO) in milliseconds; -1 disables
[in]soSendTimeoutMillisSend timeout (SO_SNDTIMEO) in milliseconds; -1 disables
[in]tcpNoDelayWhether to disable Nagle’s algorithm (TCP_NODELAY)
[in]keepAliveWhether to enable TCP keep-alive (SO_KEEPALIVE)
[in]nonBlockingWhether to immediately make the accepted socket non-blocking
Returns
A configured Socket object representing the connected client
Exceptions
SocketExceptionIf:
  • The server socket is not bound or listening
  • accept() fails
  • No client is waiting in non-blocking mode (EWOULDBLOCK, EAGAIN)
  • Socket configuration (timeouts, buffers, etc.) fails after accept()
Precondition
Server socket must be open, bound, and in listening state.
Postcondition
A new Socket is returned on success, or an exception is thrown on failure.
See also
acceptNonBlocking(), tryAccept(), setNonBlocking(), setSoRecvTimeout(), setSoSendTimeout()

◆ acceptNonBlocking()

std::optional< Socket > 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,
int soRecvTimeoutMillis = -1,
int soSendTimeoutMillis = -1,
bool tcpNoDelay = true,
bool keepAlive = false,
bool nonBlocking = false ) const
nodiscard

Attempts to accept a client connection in non-blocking mode and returns a fully configured Socket.

This method calls the system accept() in non-blocking mode to check for pending client connections:

  • If a client is ready, it wraps the accepted connection into a configured Socket object.
  • If no client is waiting, it returns std::nullopt without throwing.

🔁 Blocking Behavior

  • If the server socket is in blocking mode (default), this call blocks until a client connects.
  • If the socket is in non-blocking mode (setNonBlocking(true)), it returns immediately:
    • If a client is ready, returns a configured Socket.
    • If no client is pending, returns std::nullopt.

⚙️ Configuration

If a client is accepted, the returned Socket will be configured using the following options:

  • recvBufferSize / sendBufferSize: OS-level socket buffers (SO_RCVBUF, SO_SNDBUF)
  • internalBufferSize: Internal buffer used by read() and read<T>()
  • soRecvTimeoutMillis: Read timeout in milliseconds (SO_RCVTIMEO)
  • soSendTimeoutMillis: Send timeout in milliseconds (SO_SNDTIMEO)
  • tcpNoDelay: Disables Nagle’s algorithm for lower latency (TCP_NODELAY)
  • keepAlive: Enables TCP keep-alive probes (SO_KEEPALIVE)
  • nonBlocking: If true, the accepted socket is made non-blocking immediately

⚠️ Notes

  • This method does not use select(), poll(), or epoll() internally.
  • It is ideal for event-loop and polling-based architectures where you explicitly check for readiness.
  • Socket behavior is determined entirely by whether setNonBlocking(true) was called on the server socket.

🧠 Example

ServerSocket server(8080);
server.bind();
server.listen();
server.setNonBlocking(true);
while (true) {
auto client = server.acceptNonBlocking(
8192, 8192, 8192,
5000, 1000,
true, true, true);
if (client) {
handleClient(*client);
} else {
// No connection yet; do other work
}
}

Parameters
[in]recvBufferSizeOptional socket receive buffer size (SO_RCVBUF)
[in]sendBufferSizeOptional socket send buffer size (SO_SNDBUF)
[in]internalBufferSizeInternal buffer size for read<T>()
[in]soRecvTimeoutMillisRead timeout in milliseconds (SO_RCVTIMEO); -1 disables
[in]soSendTimeoutMillisSend timeout in milliseconds (SO_SNDTIMEO); -1 disables
[in]tcpNoDelayDisables Nagle's algorithm (TCP_NODELAY) if true (default: true)
[in]keepAliveEnables TCP keep-alive probes (SO_KEEPALIVE) if true
[in]nonBlockingSets the accepted socket to non-blocking mode if true
Returns
A configured Socket if a client is pending, or std::nullopt if no connection is ready
Exceptions
SocketExceptionif:
  • The server socket is invalid or closed
  • accept() fails due to a system error (excluding EWOULDBLOCK or EAGAIN)
Precondition
The server socket must be bound and listening
Postcondition
Returns a connected Socket or std::nullopt if no client is available
See also
accept(), acceptBlocking(), tryAccept(), setNonBlocking(), setSoRecvTimeout(), setTcpNoDelay()

◆ bind() [1/4]

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.

  • Preconditions: The socket must have been created successfully (via the constructor) but must not be already bound or listening.
  • Typical usage: Call bind() after configuring any desired socket options (such as address reuse) and before calling listen().
  • Effect: Once bind() succeeds, the server socket is associated with the local port specified during construction, and is ready to transition to listening mode with listen().
Note
  • If you want to override the default address reuse behavior or other options, you must call the corresponding setter methods before calling bind(). After bind() is called, changes to those options will have no effect.
  • On error, this function throws a SocketException containing the specific error code and message.
  • This function is cross-platform and works on both Windows and Unix-like systems.
Exceptions
SocketExceptionif the bind operation fails (for example, if the port is already in use or insufficient permissions).
Precondition
_selectedAddrInfo must not be null.
The socket must not be already bound.
Postcondition
The socket is bound to the specified address and port.
See also
setReuseAddress(), listen(), ServerSocket(Port)
server.setReuseAddress(true); // Optional: customize before binding
server.bind();
server.listen();
TCP server socket abstraction for cross-platform C++ networking.
Definition ServerSocket.hpp:100

◆ bind() [2/4]

void Socket::bind ( )

Binds the client socket to all interfaces using an ephemeral port.

This overload delegates to the default configuration — bind to any interface, with any available port. Equivalent to calling bind("", 0).

Exceptions
SocketExceptionif binding fails or the socket is already bound.

◆ bind() [3/4]

void Socket::bind ( Port port)

Binds the client socket to all interfaces (INADDR_ANY) using the specified port.

This overload binds to all available network interfaces using a specific local port. Equivalent to calling bind("", port).

Parameters
[in]portPort number to bind to.
Exceptions
SocketExceptionif binding fails or the socket is already bound.

◆ bind() [4/4]

void Socket::bind ( std::string_view localHost,
Port port )

Binds the client socket to a specific local IP address and/or port.

This method provides fine-grained control over the local endpoint from which a client socket originates. It supports both IPv4 and IPv6 resolution, dual-stack addressing, and wildcard or specific local interfaces.

Common Use Cases:

  • P2P or NAT traversal clients requiring fixed source ports
  • Multihomed systems selecting a specific local interface
  • Unit testing with known local port bindings
  • UDP clients that do not connect but still need a listening endpoint

This method must be called after the socket is constructed and before connect(). It can only be called once; repeated calls will throw. Internally uses getaddrinfo() for resolution and retries all returned addresses until binding succeeds.

Parameters
[in]localHostA local IP address or hostname to bind to (e.g., "127.0.0.1" or "::1").
[in]portPort number to bind to. Use 0 to allow the OS to auto-assign one.
Exceptions
SocketExceptionif resolution or binding fails, or if the socket is already bound.
See also
connect()
setReuseAddress()
getReuseAddress()

◆ cleanup() [1/2]

void ServerSocket::cleanup ( )
protected

Cleans up internal resources and resets the server socket state.

This internal method ensures proper teardown of socket-related resources without throwing exceptions. It is used by destructors and error-handling code to guarantee that:

Behavior

  • If the socket is open, it is closed using CloseSocket()
  • Socket descriptor is invalidated by setting it to INVALID_SOCKET
  • Address info pointers are reset to null
  • Internal state flags are cleared

This method is noexcept-safe and must never throw. It is typically used in destructors, move operations, and failure paths to ensure consistent and exception-safe resource management.

Note
Errors during socket closure are silently ignored.
This method does not throw; use cleanupAndThrow() if you need exception propagation.
See also
close(), cleanupAndThrow(), cleanupAndRethrow()

◆ cleanup() [2/2]

void Socket::cleanup ( )
protected

Internal helper that closes the socket and clears address resolution state.

This method performs safe resource cleanup for the client socket. It is intended to be reused across error-handling paths to ensure that partially initialized socket state is properly discarded, avoiding leaks or undefined behavior.


⚙️ Behavior


🔒 Safety

  • It is safe to call this method multiple times; redundant socket closes are prevented
  • Designed to be noexcept and side-effect free beyond its resource cleanup
  • Intended for use within exception paths only (never throws)

Note
This method is used internally by cleanupAndThrow() and cleanupAndRethrow() to centralize socket cleanup logic during construction or reconfiguration failures.
Warning
This method does not throw. Use cleanupAndThrow() or cleanupAndRethrow() when control flow needs to propagate an error after cleanup.
See also
cleanupAndThrow(), cleanupAndRethrow(), CloseSocket(), SocketException

◆ cleanupAndRethrow() [1/2]

void ServerSocket::cleanupAndRethrow ( )
protected

Cleans up internal resources and rethrows the current exception.

This method is used in exception-handling blocks to perform safe cleanup of the ServerSocket's internal state and then rethrow the original exception. It ensures that:

  • The socket descriptor is closed if still open
  • Address resolution memory (_srvAddrInfo) is freed
  • All internal state flags are reset

This guarantees consistent resource teardown in exception paths, and supports strong exception safety.

Usage Example

try {
// some operation that may throw
} catch (...) {
}
void cleanupAndRethrow()
Cleans up internal resources and rethrows the current exception.
Definition ServerSocket.cpp:135
Exceptions
Rethrowsthe currently active exception.
Note
This method must be called only from inside a catch block.
It preserves the original exception type and message.
See also
cleanup(), cleanupAndThrow()

◆ cleanupAndRethrow() [2/2]

void Socket::cleanupAndRethrow ( )
protected

Cleans up socket resources and rethrows the currently active exception.

This method is intended for use within a catch block to safely clean up a partially initialized or failed Socket before rethrowing the active exception. It ensures that all client-side socket resources are properly released, including the socket descriptor and any resolved address info, before propagating the error.


⚙️ Behavior

Internally delegates to cleanup() to:

Then immediately rethrows the current exception using throw;.


⚠️ Usage Notes

  • This method must be called from within a catch block. If no active exception is present, calling throw; results in undefined behavior.
  • Do not pass an exception object manually. throw; preserves the full exception context, including type, stack trace, and nested information.

🧠 Example

try {
} catch (const SocketException&) {
cleanupAndRethrow(); // Ensure resources are freed, then rethrow
}
void setReceiveBufferSize(std::size_t size)
Sets the socket's receive buffer size (SO_RCVBUF).
Definition SocketOptions.cpp:107
void setTcpNoDelay(bool on)
Enables or disables Nagle’s algorithm (TCP_NODELAY) on TCP sockets.
Definition SocketOptions.cpp:264
void cleanupAndRethrow()
Cleans up socket resources and rethrows the currently active exception.
Definition Socket.cpp:115
Exceptions
SocketExceptionAlways rethrows the currently active exception
See also
cleanup(), cleanupAndThrow()
SocketException
CloseSocket()

◆ cleanupAndThrow() [1/2]

void ServerSocket::cleanupAndThrow ( int errorCode)
protected

Cleans up internal resources and throws a SocketException.

This method is used when a fatal socket error occurs during construction or setup. It ensures that:

  • The socket descriptor is closed if still valid
  • All allocated resources (e.g., addrinfo) are released
  • Internal state is reset

After cleanup, a SocketException is thrown with the provided error code. This ensures RAII-compliant error handling and prevents resource leaks in failure paths.

Behavior

Parameters
[in]errorCodeThe error code to propagate via SocketException
Exceptions
SocketExceptionAlways throws after cleaning up internal state
Note
This method is typically used in constructors or setup functions like bind() when a system error occurs and recovery is not possible.
See also
cleanup(), cleanupAndRethrow(), SocketException

◆ cleanupAndThrow() [2/2]

void Socket::cleanupAndThrow ( int errorCode)
protected

Closes the socket, resets internal state, and throws a SocketException.

This method performs safe cleanup of all internal socket resources and throws a SocketException with the specified error code and human-readable message. It is used to centralize error handling during socket creation or connection setup, ensuring that no resources are leaked if initialization fails.


⚙️ Behavior

Internally, this method delegates to cleanup() to:

It then throws a SocketException with:

  • The provided errorCode
  • The result of SocketErrorMessage(errorCode)

🧠 Example

{
}
SOCKET getSocketFd() const noexcept
Retrieves the native socket handle (file descriptor or OS-level handle).
Definition SocketOptions.hpp:275
void connect(int timeoutMillis=-1)
Establishes a TCP connection to the remote host with optional timeout control.
Definition Socket.cpp:165
void cleanupAndThrow(int errorCode)
Closes the socket, resets internal state, and throws a SocketException.
Definition Socket.cpp:109
int GetSocketError()
Definition common.hpp:246
constexpr SOCKET SOCKET_ERROR
Definition common.hpp:265

Parameters
[in]errorCodeThe error code to report in the thrown SocketException
Exceptions
SocketExceptionAlways throws after cleanup
See also
cleanup()
cleanupAndRethrow()
SocketException
SocketErrorMessage()

◆ close() [1/2]

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:

  • All file descriptors or handles associated with the server socket are released.
  • This operation is idempotent: calling close() multiple times on the same socket is safe, but only the first call has effect.
  • Existing client sockets returned by accept() are unaffected; you must close them individually.
  • On many systems, closing a socket that is actively being used may result in a SocketException if a system error occurs.
  • After closing, you should not use this ServerSocket object for further network operations.

Example usage:

server.bind();
server.listen();
// ... handle clients ...
server.close(); // Clean up when done
Exceptions
SocketExceptionIf an error occurs while closing the socket (for example, if the underlying system call fails).
Note
On some systems, closing a socket with active client connections does not forcibly disconnect clients, but simply prevents new connections from being accepted.
Always close your sockets when finished to prevent resource leaks!

◆ close() [2/2]

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:

  1. Closes the underlying socket descriptor
  2. Releases address information resources
  3. Resets internal state

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).

Example Usage

Socket sock("example.com", 80);
sock.connect();
// ... use socket ...
sock.close(); // Explicitly close when done
Socket(SOCKET client, const sockaddr_storage &addr, socklen_t len, std::size_t recvBufferSize=DefaultBufferSize, std::size_t sendBufferSize=DefaultBufferSize, std::size_t internalBufferSize=DefaultBufferSize, int soRecvTimeoutMillis=-1, int soSendTimeoutMillis=-1, bool tcpNoDelay=true, bool keepAlive=false, bool nonBlocking=false)
Wraps an accepted TCP client socket with optional tuning parameters.
Definition Socket.cpp:12

Resource Management

  • Socket is automatically closed in destructor if not done explicitly
  • Safe to call multiple times (subsequent calls have no effect)
  • Frees system resources immediately rather than waiting for destruction
Exceptions
SocketExceptionIf the close operation fails due to:
  • System resource errors
  • Invalid socket state
  • Platform-specific network errors
Note
This method is not thread-safe. Do not call close() while other threads are performing operations on the same Socket instance.
See also
shutdown() For finer control over connection termination
~Socket() Destructor that automatically closes the socket
isValid() Check if socket is still valid after closing
Exceptions
SocketExceptionon error.

◆ connect()

void Socket::connect ( int timeoutMillis = -1)

Establishes a TCP connection to the remote host with optional timeout control.

Attempts to connect to the remote host and port specified during Socket construction. This method supports both blocking and non-blocking connection attempts, depending on the timeoutMillis parameter.

Connection Modes

  • Blocking Mode (timeoutMillis < 0):
    • Performs a traditional blocking connect().
    • The call blocks until the connection succeeds or fails.
    • Best suited for synchronous applications.
  • Non-blocking Mode with Timeout (timeoutMillis >= 0):
    • Temporarily switches the socket to non-blocking mode.
    • Initiates a connection and waits for readiness using select().
    • Throws an exception if the connection does not complete within the timeout period.
    • Restores original blocking mode automatically (RAII).
    • Recommended for GUI, async, or responsive applications.

Implementation Details

  • Uses ::connect() followed by ::select() to monitor write readiness.
  • Once writable, uses getsockopt(SO_ERROR) to determine if the connection succeeded.
  • On POSIX systems, if the socket descriptor exceeds FD_SETSIZE, a SocketException is thrown.
  • The socket's original blocking mode is automatically restored using ScopedBlockingMode.

Platform Notes

  • On POSIX, select() monitors the socket using fd_set; the file descriptor must be < FD_SETSIZE (typically 1024).
  • On Windows, select() ignores its first parameter and allows descriptors up to ~2030, but limits still apply.

Example Usage

Socket sock("example.com", 80);
// Blocking connect (waits indefinitely)
sock.connect();
// Connect with a 5-second timeout (non-blocking)
try {
sock.connect(5000);
} catch (const SocketTimeoutException& timeout) {
std::cerr << "Connection timed out\\n";
} catch (const SocketException& ex) {
std::cerr << "Connect failed: " << ex.what() << "\\n";
}
Parameters
[in]timeoutMillisConnection timeout in milliseconds:
  • Negative: use blocking mode (no timeout)
  • Zero or positive: maximum wait duration in milliseconds
Exceptions
SocketTimeoutExceptionIf the connection did not complete before the timeout.
SocketExceptionIf:
  • No address information was resolved
  • The socket is invalid or closed
  • The connection fails (e.g., refused, unreachable, or timed out)
  • The descriptor exceeds platform-specific select() limits
  • getsockopt() reports an error after select returns success
Note
This method is not thread-safe. Do not call connect() on the same Socket instance concurrently from multiple threads.
See also
isConnected() Check if the connection was established
close() Close the socket
setNonBlocking() Permanently change blocking mode
waitReady() Low-level readiness polling with timeout

◆ discard()

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. If the chunk size is 0, the method throws an exception.

Parameters
[in]nNumber of bytes to discard. Must be greater than 0.
[in]chunkSizeSize (in bytes) of the temporary buffer used for reading/discarding. Default is 1024.
Exceptions
SocketExceptionIf:
  • The socket is invalid
  • An error occurs during recv()
  • The connection is closed before all n bytes are discarded
  • chunkSize is 0
Note
For optimal performance on high-throughput streams or large discards, consider using a larger chunk size (e.g., 4096 or 8192).

◆ getDefaultInternalBufferSize()

std::size_t jsocketpp::ServerSocket::getDefaultInternalBufferSize ( ) const
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().

Returns
The current default internal buffer size in bytes.
See also
setDefaultInternalBufferSize()
getEffectiveInternalBufferSize()
DefaultBufferSize

◆ getDefaultReceiveBufferSize()

std::size_t jsocketpp::ServerSocket::getDefaultReceiveBufferSize ( ) const
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.

Returns
Current buffer size in bytes
See also
setDefaultReceiveBufferSize()
DefaultBufferSize
accept()

◆ getDefaultSendBufferSize()

std::size_t jsocketpp::ServerSocket::getDefaultSendBufferSize ( ) const
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.

Returns
Current send buffer size in bytes
See also
setDefaultSendBufferSize()
DefaultBufferSize
accept()

◆ getEffectiveInternalBufferSize()

std::size_t jsocketpp::ServerSocket::getEffectiveInternalBufferSize ( const std::optional< std::size_t > internalBufferSize) const
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).

Parameters
[in]internalBufferSizeOptional buffer size override for a single operation.
Returns
The effective internal buffer size to use.
See also
DefaultBufferSize
setInternalBufferSize()
Socket::readLine()
Socket::getInternalBufferSize()

◆ getEffectiveReceiveBufferSize()

std::size_t jsocketpp::ServerSocket::getEffectiveReceiveBufferSize ( const std::optional< std::size_t > recvBufferSize) const
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).

Parameters
[in]recvBufferSizeOptional size. If unset, defaults to _defaultReceiveBufferSize.
Returns
The effective buffer size to use.
See also
setDefaultReceiveBufferSize()
getDefaultReceiveBufferSize()
DefaultBufferSize

◆ getEffectiveSendBufferSize()

std::size_t jsocketpp::ServerSocket::getEffectiveSendBufferSize ( std::optional< std::size_t > sendBufferSize) const
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).

Parameters
[in]sendBufferSizeOptional size. If unset, defaults to _defaultSendBufferSize.
Returns
The effective buffer size to use for send operations.
See also
setSendBufferSize()
getSendBufferSize()
DefaultBufferSize

◆ getLocalIp()

std::string Socket::getLocalIp ( bool convertIPv4Mapped = true) const
nodiscard

Retrieves the local IP address this socket is bound to.

This method returns the local interface IP address assigned to the socket, in numeric string format (e.g., "127.0.0.1", "192.168.1.5", or "fe80::1"). It reflects the interface to which the socket is bound — either explicitly via bind() or implicitly by the system during connect() or accept().


IPv4-Mapped IPv6 Behavior

If the socket is using IPv6 and the local address is an IPv4-mapped IPv6 address (e.g., ::ffff:192.0.2.1), and convertIPv4Mapped == true, this method will return the simplified IPv4 form ("192.0.2.1").


Use Cases

  • Determine which local interface the socket is bound to
  • Diagnose behavior in multi-homed systems or NAT environments
  • Report or log client-side or server-side connection endpoints

Example

Socket client("example.com", 443);
std::cout << "Local IP: " << client.getLocalIp() << "\n";
Parameters
[in]convertIPv4MappedWhether to normalize IPv4-mapped IPv6 addresses to plain IPv4 (default = true)
Returns
The local IP address as a string.
Exceptions
SocketExceptionif the socket is not bound or the address cannot be retrieved.
See also
getLocalPort()
getLocalSocketAddress()
bind(), connect(), accept()

◆ getLocalPort() [1/2]

Port ServerSocket::getLocalPort ( ) const
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.

Note
This method is thread safe.
Returns
The local port number, or 0 if the socket is not bound.
Exceptions
SocketExceptionif there is an error retrieving the port number.
ServerSocket server(0); // Bind to any available port
server.bind();
Port port = server.getLocalPort();
std::cout << "Server bound to port: " << port << std::endl;
std::uint16_t Port
Type alias representing a TCP or UDP port number (1–65535).
Definition common.hpp:392

◆ getLocalPort() [2/2]

Port Socket::getLocalPort ( ) const
nodiscard

Retrieves the local port number this socket is bound to.

This method returns the port number that the socket is currently bound to on the local system. It can be used after an explicit call to bind(), or implicitly after a successful connect() or accept() where the OS assigns an ephemeral port.

The value is returned in host byte order and reflects the actual bound state of the socket. If the socket is not yet bound, an exception will be thrown.


Use Cases

  • Determine which port was assigned during connect() (for ephemeral clients)
  • Confirm fixed port bindings in server or P2P applications
  • Log local endpoints for diagnostics or auditing

Example

Socket client("example.com", 443);
std::cout << "Local port: " << client.getLocalPort() << "\n";
Returns
The local port number in host byte order (as a 16-bit unsigned integer).
Exceptions
SocketExceptionif the socket is not bound or the port cannot be retrieved.
See also
getLocalIp()
getRemotePort()
bind()
connect()

◆ getLocalSocketAddress() [1/2]

std::string ServerSocket::getLocalSocketAddress ( ) const
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.

Note
This method is thread safe.
Returns
The local socket address as a string, or an empty string if the socket is not bound.
Exceptions
SocketExceptionif there is an error retrieving the address.
ServerSocket server(8080);
server.bind();
std::cout << "Server bound to: " << server.getLocalSocketAddress() << std::endl;

◆ getLocalSocketAddress() [2/2]

std::string Socket::getLocalSocketAddress ( bool convertIPv4Mapped = true) const
nodiscard

Retrieves the full local socket address in the form "IP:port".

This method returns a combined representation of the socket's local IP address and port number, formatted as a string. It is valid after the socket has been bound (explicitly via bind() or implicitly via connect() or accept()).


Format

  • For IPv4: "127.0.0.1:8080"
  • For IPv6: "[::1]:443" (square brackets included for URI compatibility)
  • If convertIPv4Mapped == true, IPv4-mapped IPv6 addresses (::ffff:192.0.2.1) will be normalized to plain IPv4 (192.0.2.1)

Use Cases

  • Diagnostics: determine which interface/port the socket is bound to
  • Logging: record local endpoints for debugging or analytics
  • Multi-homed applications: distinguish binding behavior across interfaces

Example

Socket client("example.com", 443);
std::cout << "Bound locally to: " << client.getLocalSocketAddress() << "\n";
Parameters
[in]convertIPv4MappedWhether to normalize IPv4-mapped IPv6 addresses to pure IPv4
Returns
A string representing the local socket address in the form "IP:port" or "[IPv6]:port"
Exceptions
SocketExceptionif the local address or port cannot be retrieved
See also
getLocalIp()
getLocalPort()
getRemoteSocketAddress()

◆ getRemoteIp()

std::string Socket::getRemoteIp ( bool convertIPv4Mapped = true) const
nodiscard

Retrieves the IP address of the remote peer this TCP socket is connected to.

This method returns the remote IP address of the connected peer. It is only valid after a successful connect() or after a socket has been returned by accept().


🌍 Behavior

  • Returns an IPv4 or IPv6 address depending on the remote endpoint
  • For IPv6 sockets with IPv4-mapped addresses, set convertIPv4Mapped to true to return them in normalized IPv4 form

Use Cases

  • Logging connected clients (e.g. "Accepted from 192.168.1.2")
  • Verifying peer identity or interface binding
  • Building connection summaries

Example

Socket client = serverSocket.accept();
std::cout << "Client IP: " << client.getRemoteIp() << "\n";
std::string getRemoteIp(bool convertIPv4Mapped=true) const
Retrieves the IP address of the remote peer this TCP socket is connected to.
Definition Socket.cpp:379
Parameters
[in]convertIPv4MappedWhether to normalize IPv4-mapped IPv6 addresses (default = true)
Returns
IP address string of the connected peer
Exceptions
SocketExceptionif the socket is not connected or the remote address cannot be retrieved
See also
getRemotePort()
getRemoteSocketAddress()
connect(), accept()

◆ getRemotePort()

Port Socket::getRemotePort ( ) const
nodiscard

Retrieves the port number of the remote peer this TCP socket is connected to.

This method returns the TCP port number of the peer to which this socket is currently connected. It is valid after a successful connect() or after a client socket has been accepted from a ServerSocket.


Use Cases

  • Logging and monitoring TCP connections
  • Displaying peer socket addresses for user interfaces or diagnostic tools
  • Validating or filtering based on peer ports (e.g., ephemeral port detection)

Example

Socket client = serverSocket.accept();
std::cout << "Client is connected on port: " << client.getRemotePort() << "\n";
Port getRemotePort() const
Retrieves the port number of the remote peer this TCP socket is connected to.
Definition Socket.cpp:396
Returns
The port number of the connected peer (host byte order).
Exceptions
SocketExceptionif the socket is not connected or the port cannot be retrieved.
See also
getRemoteIp()
getRemoteSocketAddress()
connect(), accept()

◆ getRemoteSocketAddress()

std::string Socket::getRemoteSocketAddress ( bool convertIPv4Mapped = true) const
nodiscard

Get the connected peer's socket address as a formatted string.

Combines the IP address and port of the connected peer into a single human-readable string. This is valid after a successful connect() or after a connection is accepted from a ServerSocket.


Format

  • For IPv4: "192.168.0.42:443"
  • For IPv6: "[fe80::1]:443" (square brackets added for URI compatibility)

Use Cases

  • Connection logging (e.g., "Accepted from: IP:port")
  • Debugging or monitoring active connections
  • UI and CLI-friendly representation of connected peers

Example

Socket client = serverSocket.accept();
std::cout << "Client connected from: " << client.getRemoteSocketAddress() << "\n";
std::string getRemoteSocketAddress(bool convertIPv4Mapped=true) const
Get the connected peer's socket address as a formatted string.
Definition Socket.cpp:413

Parameters
[in]convertIPv4MappedWhether to normalize IPv4-mapped IPv6 addresses.
Returns
A string of the form "IP:port" or "[IPv6]:port".
Exceptions
SocketExceptionif the socket is not connected or the address cannot be retrieved.
See also
getRemoteIp()
getRemotePort()
connect(), accept()

◆ isBound() [1/2]

bool jsocketpp::ServerSocket::isBound ( ) const
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().

Returns
true if the socket is bound, false otherwise.

◆ isBound() [2/2]

bool jsocketpp::Socket::isBound ( ) const
inlinenodiscardnoexcept

Indicates whether the socket has been explicitly bound to a local address and/or port.

Returns true if the socket has successfully completed a call to one of the bind() overloads. Binding is optional for client sockets, but is often required in advanced scenarios such as:

  • Assigning a fixed local port for NAT traversal or predictable communication
  • Selecting a specific local interface in multihomed environments
  • Participating in multicast, broadcast, or P2P communication setups

Binding must occur before the socket is connected. Attempting to bind after connect() will throw.

Example

Socket socket("example.com", 443);
socket.bind("0.0.0.0", 12345); // Use fixed source port
socket.connect();
Returns
true if the socket has been bound to a local address/port, false otherwise.
See also
bind()

◆ isClosed() [1/2]

bool jsocketpp::ServerSocket::isClosed ( ) const
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.

Returns
true if the socket has been closed, false if it is still open.
See also
isValid(), close()

◆ isClosed() [2/2]

bool jsocketpp::Socket::isClosed ( ) const
inlinenodiscardnoexcept

Reports whether the socket has been closed or invalidated.

Returns true if the socket is no longer usable—either because it was explicitly closed, or because the underlying file descriptor has been released or never initialized.

This method does not perform any system-level check or probing. It simply inspects the internal socket descriptor (getSocketFd()) and considers the socket closed if it is equal to INVALID_SOCKET. This reflects the same mechanism used internally for error detection and safety throughout the library.

Example

Socket sock("example.com", 443);
assert(!sock.isClosed());
sock.connect();
sock.close(); // assume you define a close() method
assert(sock.isClosed()); // true
Returns
true if the socket is closed or uninitialized, false otherwise.
Note
Once closed, the socket cannot be reused or reopened. Create a new Socket instance instead.
See also
isConnected()
isBound()

◆ isConnected()

bool jsocketpp::Socket::isConnected ( ) const
inlinenodiscardnoexcept

Indicates whether the socket has been successfully connected to a remote host.

Returns true if the socket has completed a successful connection attempt using connect(). This reflects the internal connection state as tracked by the library—it does not actively probe the socket or verify that the connection is still alive at the network layer.

Use this method to check whether it is valid to perform send/receive operations. A socket transitions to the "connected" state only after a successful call to connect() with no subsequent errors or closures.

Example

Socket socket("example.com", 443);
socket.connect();
if (socket.isConnected()) {
socket.send(...);
}
Returns
true if the socket is in the connected state, false otherwise.
See also
connect()

◆ isInputShutdown()

bool jsocketpp::Socket::isInputShutdown ( ) const
inlinenodiscardnoexcept

Checks whether the socket's input stream has been shutdown.

Returns true if the socket has been explicitly shutdown for reading via shutdown(ShutdownMode::Read) or shutdown(ShutdownMode::Both). After input shutdown:

  • Any further read operations will return EOF or throw exceptions.
  • The socket cannot receive new data from the peer.

This method tracks shutdown state internally—it does not query the operating system (as no portable API exists for that). It reflects the local state at the time of the last shutdown() call on this socket.

Use Cases

  • Preventing redundant or invalid read calls after a graceful shutdown.
  • Verifying application-level protocol state transitions.
  • Detecting half-closed connections during teardown.
Returns
true if the input (receive) side of the socket has been shutdown; false otherwise.
See also
shutdown()
isOutputShutdown()
isConnected()
read(), readExact(), readUntil()

◆ isListening()

bool jsocketpp::ServerSocket::isListening ( ) const
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.

Returns
true if the socket is listening for connections, false otherwise.

◆ isOutputShutdown()

bool jsocketpp::Socket::isOutputShutdown ( ) const
inlinenodiscardnoexcept

Checks whether the socket's output stream has been shutdown.

Returns true if the socket has been explicitly shutdown for writing via shutdown(ShutdownMode::Write) or shutdown(ShutdownMode::Both). After output shutdown:

  • All subsequent write operations will fail with a SocketException.
  • The system sends a FIN packet to the peer, indicating no more data will be sent.

This method tracks shutdown state internally—it does not query the operating system, as no portable getsockopt() mechanism exists to detect output shutdown externally.

Use Cases

  • Enforcing proper protocol shutdown (e.g. sending EOF before receiving response).
  • Avoiding invalid writes after intentionally shutting down output.
  • Debugging and verifying application-level connection state.
Returns
true if the output (send) side of the socket has been shutdown; false otherwise.
See also
shutdown()
isInputShutdown()
isConnected()
write(), writeAll(), writePrefixed()

◆ isValid() [1/2]

bool jsocketpp::ServerSocket::isValid ( ) const
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.

Note
  • Returns true if the server socket has been created and not yet closed.
  • Returns false if the socket has not been created, or has already been closed (and resources released).
Returns
true if the server socket is open and valid; false otherwise.
See also
close(), isClosed()

◆ isValid() [2/2]

bool jsocketpp::Socket::isValid ( ) const
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.

Implementation Details

  • Checks if internal socket descriptor (getSocketFd()) is not INVALID_SOCKET
  • Fast, constant-time operation (O(1))
  • Thread-safe (const noexcept)
  • Does not perform any system calls

Example Usage

Socket sock("example.com", 8080);
if (sock.isValid()) {
// Socket is ready for connect()
sock.connect();
}
sock.close();
assert(!sock.isValid()); // Socket is now invalid
Returns
true if the socket is valid and ready for use, false if the socket has been closed or failed to initialize.
Note
This method only checks the socket's validity, not its connection state. A valid socket may or may not be connected to a remote host.
See also
isConnected() Check if socket is actually connected
close() Invalidates the socket

◆ listen()

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().

  • How it works: After binding the socket to a local address and port (via bind()), call listen() to have the operating system start queueing incoming connection requests. Only after calling listen() can the server accept connections.
  • Backlog parameter: The backlog argument specifies the maximum number of pending client connections that can be queued before connections are refused. If not specified, the system default (SOMAXCONN) is used.
  • Usage sequence: Typical usage is: ServerSocket sock(port); sock.bind(); sock.listen();
Note
  • You must call bind() before calling listen(). If the socket is not bound, this call will fail.
  • The backlog parameter is a hint to the operating system. The actual queue length may be capped by system configuration (e.g., /proc/sys/net/core/somaxconn on Linux). On Windows, SOMAXCONN may be very large, so a smaller value (e.g., 128) is recommended for most applications.
  • On success, the socket is ready for calls to accept().
  • On error (e.g., socket not bound, invalid arguments, system resource exhaustion), a SocketException is thrown with details.
Exceptions
SocketExceptionif the listen operation fails.
Precondition
bind() must be called successfully before this.
Postcondition
The server socket is now listening for incoming connections.
See also
bind(), accept(), ServerSocket(Port)
server.setReuseAddress(true); // Optional: set before bind
server.bind();
server.listen();
while (true) {
jsocketpp::Socket client = server.accept();
// Handle client connection
}

◆ operator=() [1/4]

ServerSocket & jsocketpp::ServerSocket::operator= ( const ServerSocket & rhs)
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.

Parameters
[in]rhsThe ServerSocket to copy from (unused since deleted)
Returns
Reference to this ServerSocket (never returns since deleted)
Note
This deletion enforces RAII principles and prevents resource leaks.
See also
operator=(ServerSocket&&)
ServerSocket(ServerSocket&&)

◆ operator=() [2/4]

ServerSocket & jsocketpp::ServerSocket::operator= ( ServerSocket && rhs)
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:

  • If this socket already owns resources, they are closed before the transfer.
  • The moved-from socket is left in a valid but empty state (closed socket, null pointers).
  • No system resources are leaked during the transfer.

After the move:

  • This socket takes ownership of all resources from rhs.
  • The moved-from socket (rhs) becomes closed and can be safely destroyed.
  • All socket options, state flags, and configurations are transferred.
Parameters
[in]rhsThe ServerSocket to move resources from.
Returns
Reference to this ServerSocket (containing the moved resources).
Note
This operation is thread-safe with respect to the moved-from socket, but concurrent operations on either socket during the move may cause undefined behavior.
See also
ServerSocket(ServerSocket&&)
close()

◆ operator=() [3/4]

Socket & jsocketpp::Socket::operator= ( const Socket & rhs)
delete

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:

  • Double-closing of socket descriptors
  • Race conditions in multi-threaded code
  • Ambiguous ownership of system resources
  • Potential resource leaks

Instead of copying, use move semantics (operator=(Socket&&)) to transfer ownership of a Socket from one object to another. For example:

Socket s1("example.com", 80);
Socket s2("other.com", 8080);
s2 = std::move(s1); // OK: moves ownership from s1 to s2
s2 = s1; // Error: copying is disabled
Parameters
[in]rhsThe Socket object to copy from (unused since deleted)
Returns
Reference to this Socket (never returns since deleted)
See also
Socket(Socket&&) Move constructor for transferring socket ownership
operator=(Socket&&) Move assignment operator for transferring socket ownership

◆ operator=() [4/4]

Socket & jsocketpp::Socket::operator= ( Socket && rhs)
inlinenoexcept

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:

  1. Checks for self-assignment to prevent resource corruption
  2. Closes any existing socket connection
  3. Frees existing address information resources
  4. Takes ownership of all resources from the source socket
  5. Resets the source socket to a valid but empty state

After the move operation:

  • This socket will own and manage all resources from the source
  • The source socket (rhs) will be left in a valid but disconnected state
  • All previous resources of this socket will be properly cleaned up
Parameters
[in,out]rhsThe source Socket whose resources will be moved. After the move, rhs will be left in a valid but disconnected state.
Returns
Reference to this Socket object
Note
This operation is noexcept as it handles all cleanup internally and cannot throw exceptions. At worst, socket closure errors will be logged.
See also
Socket(Socket&&) Move constructor
Socket(const Socket&) Copy constructor (deleted)
operator=(const Socket&) Copy assignment operator (deleted)

◆ peek()

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.

Implementation Details

  • Performs a single recv() call with MSG_PEEK
  • Does not remove any bytes from the socket buffer
  • May return fewer bytes than requested if less data is available
  • Does not block indefinitely if the socket is non-blocking or has a timeout

Example Usage

std::string preview = sock.peek(4);
if (preview == "PING") {
std::string full = sock.readExact(4);
handlePing(full);
}
Parameters
[in]nMaximum number of bytes to peek at.
Returns
A string containing up to n bytes from the receive buffer.
Exceptions
SocketExceptionIf:
  • The socket is invalid
  • recv() fails
  • Connection is closed unexpectedly
Note
If you want to discard data after peeking, use read() or discard() afterward.
See also
readExact() To consume data after peek
readAvailable() For full-buffer inspection and consumption
discard() To remove bytes without copying them (future)

◆ read() [1/2]

template<>
std::string jsocketpp::Socket::read ( )
inline

Specialization of read<T>() for reading a single buffer of string data.

Reads a variable-length block of data from the socket into the internal receive buffer and returns it as a std::string. This specialization provides optimized handling for raw or text-based data streams where the amount of available data is not known in advance.

Unlike read<T>(), which reads a fixed number of bytes based on the type, this method reads up to the size of the internal buffer and returns whatever data is available, making it ideal for use cases where the protocol layer or application logic defines variable-sized records or streams.

Key Features

  • Uses _internalBuffer for efficient chunked recv() operations
  • Preserves binary data (e.g. embedded null bytes)
  • Returns actual number of bytes received (may be less than buffer size)
  • Non-blocking if data is already available (subject to socket timeout)

Implementation Details

  1. Uses _internalBuffer sized via setInternalBufferSize()
  2. Performs a single recv() call up to the buffer size
  3. Returns a std::string containing only the received portion
  4. Internal buffer is reused across calls and not resized dynamically

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Default buffer size (see @ref DefaultBufferSize)
std::string data = sock.read<std::string>();
// Increase buffer size for larger payloads
sock.setInternalBufferSize(4096);
std::string chunk = sock.read<std::string>();
Returns
A std::string containing up to internalBufferSize bytes of received data. The length reflects the actual bytes read from the socket.
Exceptions
SocketExceptionIf:
  • The socket is closed (recv() == 0)
  • A network error occurs (recv() == SOCKET_ERROR)
  • The socket is in an invalid state or not connected
Note
This specialization differs from the generic read<T>():
  • It supports reading variable-length data
  • It does not attempt to construct a specific object type
  • It is suitable for stream-based protocols, logging, or framed text
See also
read() Generic fixed-size reader for POD types
setInternalBufferSize() To control the read buffer size
write() For sending text or binary data
readUntil() For delimiter-based stream parsing

◆ read() [2/2]

template<typename T>
T jsocketpp::Socket::read ( )
inlinenodiscard

Reads a fixed-size, trivially copyable object of type T from the socket.

Performs a binary-safe read of exactly sizeof(T) bytes from the socket and constructs an instance of T from the received data. This method is optimized for reading primitive types and Plain Old Data (POD) structures directly from a binary stream, without any decoding or parsing overhead.

Implementation Details

  • Allocates a temporary buffer of sizeof(T) bytes
  • Loops on recv() until all bytes are received (handles partial reads)
  • Copies the buffer into a std::array<std::byte, sizeof(T)> and performs a std::bit_cast
  • Enforces type constraint: std::is_trivially_copyable_v<T> and std::is_standard_layout_v<T>
  • Performs no byte order conversion, alignment, or field normalization

Example Usage

Socket sock("example.com", 9000);
sock.connect();
int count = sock.read<int>();
double ratio = sock.read<double>();
struct Header {
uint32_t id;
uint16_t flags;
char tag[16];
};
Header h = sock.read<Header>();

Supported Types

  • Scalar types: int, float, double, etc.
  • POD structs and unions
  • Raw byte arrays or std::array<T, N>
  • Any type that satisfies std::is_trivially_copyable

Limitations

  • ❌ No pointer-based fields
  • ❌ No virtual methods or dynamic memory
  • ❌ No platform-dependent padding or ABI assumptions
  • ❌ No endianness conversion (use utility functions to normalize fields)

Thread Safety

  • ❌ Not thread-safe: do not call concurrently on the same Socket instance
  • ✅ Use separate Socket objects per thread, or synchronize externally
Template Parameters
TA trivially copyable type to read from the socket. This is enforced at compile time.
Returns
A fully initialized instance of type T with raw data populated from the stream.
Exceptions
SocketExceptionIf:
  • The socket is closed before the full sizeof(T) bytes are read
  • A network error occurs (e.g., ECONNRESET, EPIPE, ETIMEDOUT)
  • The socket is invalid, unconnected, or interrupted
Warning
Byte Order: No endianness normalization is applied. You must manually convert fields using utilities like fromNetwork() or ntohl() if reading cross-platform data.
Memory Safety: Do not use this method with types containing pointers, virtual tables, custom allocators, or layout-dependent structures. Misuse may result in undefined behavior, security vulnerabilities, or memory corruption.
Note
This method allocates a temporary buffer for each call. It does not use or affect the internal string buffer used by methods like readUntil().
See also
write() For writing fixed-size objects to the socket
readPrefixed() For reading length-prefixed dynamic types
setSoRecvTimeout() To configure read timeout behavior
isConnected() To check whether the socket is currently usable

◆ readAtMost()

std::string Socket::readAtMost ( std::size_t n) const

Performs a single best-effort read of up to n bytes from the socket.

This method attempts to read up to n bytes from the socket using a single recv() call. It is designed for responsiveness: it returns as soon as any data is available—whether that's the full n bytes, fewer bytes, or even zero if the connection was closed.

This is a low-overhead, non-looping read ideal for event-driven designs, polling, or non-blocking sockets. It differs from readExact() in that it does not retry or wait for the full amount of data.

Implementation Details

  • Calls recv() exactly once with a preallocated buffer
  • Returns available data immediately (up to n bytes)
  • Resizes the result to the actual number of bytes read
  • Throws on socket errors or if the connection is closed

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Try to read up to 512 bytes
std::string chunk = sock.readAtMost(512);
if (!chunk.empty()) {
process(chunk);
}
Parameters
[in]nMaximum number of bytes to read in one call. Must be greater than 0.
Returns
A std::string containing 0 to n bytes of data. An empty string means the connection was closed or nothing was available (e.g., non-blocking mode).
Exceptions
SocketExceptionIf:
  • The socket is invalid, disconnected, or closed (EBADF, ENOTCONN, etc.)
  • A network error occurs during the recv() operation
  • The connection was closed by the peer (recv() returned 0)
  • Memory allocation fails during buffer allocation
Note
Unlike readExact(), this method does not retry or loop. Use with care in protocols that depend on strict byte counts.
See also
readExact() For guaranteed-length blocking reads
readUntil() For delimiter-based parsing
setNonBlocking() To configure socket non-blocking behavior
setSoRecvTimeout() To configure read timeout

◆ readAtMostWithTimeout()

std::string Socket::readAtMostWithTimeout ( std::size_t n,
int timeoutMillis ) const

Attempts a best-effort read of up to n bytes with a timeout constraint.

Waits for the socket to become readable for up to timeoutMillis milliseconds, then performs a single recv() call to read up to n bytes of available data. This method is useful for polling-style or time-sensitive I/O operations where immediate responsiveness is more important than full data delivery.

Unlike readExact(), this method does not loop or retry to satisfy the full size. It returns as soon as data is available, or throws a SocketTimeoutException if no data arrives within the specified timeout window.

Implementation Details

  • Calls waitReady(false) to wait for data readiness
  • Performs a single recv() once readable
  • Returns the available data immediately (may be fewer than n bytes)
  • Throws on timeout, disconnection, or error
  • Returned string is resized to match actual data length

Example Usage

Socket sock("example.com", 8080);
sock.connect();
try {
// Try to read up to 1024 bytes with a 5-second timeout
std::string data = sock.readAtMostWithTimeout(1024, 5000);
std::cout << "Read " << data.size() << " bytes\n";
} catch (const SocketTimeoutException& timeoutEx) {
std::cerr << "Timeout: " << timeoutEx.what() << std::endl;
} catch (const SocketException& ex) {
std::cerr << "Socket error: " << ex.what() << std::endl;
}
Parameters
[in]nMaximum number of bytes to read in one operation. Must be > 0.
[in]timeoutMillisMaximum duration to wait for readability, in milliseconds:
  • > 0: Wait up to this time
  • 0: Poll without blocking
  • < 0: Invalid; throws SocketException
Returns
A std::string containing between 1 and n bytes of data received.
Exceptions
SocketTimeoutExceptionIf the socket remains unreadable beyond timeoutMillis.
SocketExceptionIf:
  • The socket is invalid or closed
  • The peer disconnects (recv() == 0)
  • A network/system error occurs during recv()
  • Memory allocation fails
Note
This method is ideal for polling and timeout-aware reads where partial delivery is acceptable. For guaranteed reads, use readExact(). For immediate best-effort reads without timeout, use readAtMost().
See also
readExact() For guaranteed full-length reads
readAtMost() For best-effort reads without blocking
waitReady() To wait for readiness explicitly
setSoRecvTimeout() To set socket-level timeout defaults

◆ readAvailable()

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.

Implementation Details

  • Uses ioctl (or ioctlsocket on Windows) with FIONREAD to determine readable bytes
  • If no data is available, returns an empty string immediately
  • Performs one recv() call up to the number of available bytes
  • Avoids dynamic memory allocation if no data is available

Example Usage

Socket sock("example.com", 1234);
sock.connect();
while (sock.isConnected()) {
std::string data = sock.readAvailable();
if (!data.empty()) {
handleChunk(data);
}
}
Returns
A string containing 0 or more bytes, depending on what was available at the time.
Exceptions
SocketExceptionIf:
  • ioctl/FIONREAD fails
  • recv() fails due to network error
  • Connection is closed unexpectedly
Note
This method does not wait or retry. If you want timeout-based behavior, use readAtMostWithTimeout() instead.
See also
readAtMostWithTimeout() For time-bounded partial reads
read() For fixed-size reads
readExact() For guaranteed-length reads
waitReady() To wait for socket readiness before calling this

◆ readExact()

std::string Socket::readExact ( std::size_t n) const

Reads exactly n bytes from the socket into a std::string.

Performs a fully blocking read that continues reading from the socket until the specified number of bytes (n) has been received, or an error or disconnection occurs. This method guarantees exact-length delivery and is suitable for fixed-length binary protocols or framed data.

Internally, it repeatedly calls recv() as needed to handle partial reads. It allocates a string of size n and fills it directly with received data in order, preserving byte order and content integrity.

Implementation Details

  • Uses a loop around recv() to read remaining bytes
  • Handles short reads and interruptions transparently
  • Allocates result string up front (no resizing or reallocation)
  • Does not interpret content — binary-safe and endian-agnostic

Example Usage

Socket sock("example.com", 8080);
sock.connect();
try {
// Read an exact-length header
std::string header = sock.readExact(16);
// Read an entire frame of known size
std::string frame = sock.readExact(1024);
assert(frame.size() == 1024);
} catch (const SocketException& ex) {
std::cerr << "Read failed: " << ex.what() << std::endl;
}
Parameters
[in]nThe number of bytes to read. Must be greater than zero.
Returns
A std::string containing exactly n bytes of data received from the socket.
Exceptions
SocketExceptionIf:
  • The peer closes the connection before n bytes are received
  • A read timeout occurs (e.g. ETIMEDOUT)
  • A network error or signal interruption occurs
  • The socket is invalid or unconnected (e.g. EBADF)
  • Memory allocation fails (std::bad_alloc)
Note
This method blocks until all n bytes are read or an error occurs. It is not suitable for variable-length or streaming reads.
This method returns an empty string if n == 0.
See also
read<std::string>() For best-effort, buffered reads
read<T>() For fixed-size reads of trivially copyable types
readUntil() For delimiter-based reads (e.g. lines or tokens)
setSoRecvTimeout() To configure blocking behavior

◆ readInto()

std::size_t jsocketpp::Socket::readInto ( void * buffer,
const std::size_t len ) const
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.

Implementation Details

  • Uses recv() internally with a single call
  • Returns immediately with available data
  • Does not guarantee full buffer will be filled
  • Non-blocking mode affects behavior

Example Usage

Socket sock("example.com", 8080);
sock.connect();
char buffer[1024];
size_t bytesRead = sock.readInto(buffer, sizeof(buffer));
if (bytesRead > 0) {
// Process bytesRead bytes from buffer
}
Parameters
[out]bufferPointer to pre-allocated memory buffer to store read data. Must be valid and large enough for len bytes.
[in]lenMaximum number of bytes to read (buffer size)
Returns
Number of bytes actually read (may be less than len)
Exceptions
SocketExceptionIf:
  • Socket is invalid (EBADF)
  • Connection closed by peer
  • Memory access error (EFAULT)
  • Network errors occur
See also
readIntoExact() For guaranteed full-length reads
read() Template method for type-safe reads
readUntil() For delimiter-based reading

◆ readIntoAvailable()

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.

Implementation Details

  • Uses FIONREAD (Windows or POSIX) to determine available bytes
  • Performs one recv() call into buffer for min(bufferSize, available)
  • Returns number of bytes read
  • Does nothing if no data is available

Example Usage

char buf[2048];
std::size_t received = sock.readIntoAvailable(buf, sizeof(buf));
if (received > 0) {
parse(buf, received);
}
Parameters
[out]bufferPointer to the memory where received data will be stored.
[in]bufferSizeMaximum number of bytes to store in the buffer.
Returns
The number of bytes actually read (may be 0 if no data is available).
Exceptions
SocketExceptionIf:
  • Socket is invalid
  • ioctl/FIONREAD fails
  • recv() fails
  • Connection is closed during read
Note
This method does not allocate memory and is safe to call frequently. For a string-returning variant, use readAvailable().
See also
readAvailable() For dynamic buffer version
readAtMostWithTimeout() For time-limited reads
readInto() For controlled-length reading (blocking)

◆ readIntoExact()

std::size_t jsocketpp::Socket::readIntoExact ( void * buffer,
const std::size_t len ) const
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.

Implementation Details

  • Uses readIntoInternal() with exact=true
  • Loops until all requested bytes are read
  • Handles partial reads internally
  • Throws if connection closes before all bytes received

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Read a fixed-size header
struct Header {
uint32_t messageType;
uint32_t payloadLength;
};
Header header;
sock.readIntoExact(&header, sizeof(header));
// Read exact payload length
std::vector<char> payload(header.payloadLength);
sock.readIntoExact(payload.data(), payload.size());
Parameters
[out]bufferPointer to pre-allocated memory where data should be written. Must be valid and large enough for len bytes.
[in]lenNumber of bytes to read. Method won't return until exactly this many bytes are read or an error occurs.
Returns
Number of bytes actually read (always equal to len on success)
Exceptions
SocketExceptionIf:
  • Connection closes before len bytes received
  • Socket error occurs during read
  • Memory access error (EFAULT)
  • Socket is invalid or not connected
  • Timeout occurs (if configured)
See also
readInto() For "best-effort" reads that may return partial data
read() Template method for type-safe reads
readIntoInternal() Internal implementation

◆ readIntoInternal()

std::size_t Socket::readIntoInternal ( void * buffer,
std::size_t len,
bool exact = false ) const
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.

Modes of Operation

  • Best-effort mode (exact=false):
    • Performs single recv() call
    • Returns immediately with available data
    • May return fewer bytes than requested
    • Suitable for stream processing
  • Exact mode (exact=true):
    • Guarantees all requested bytes are read
    • Loops until full length received
    • Throws if connection closes early
    • Good for protocol messages

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Best-effort read
char buf[1024];
size_t got = sock.readInto(buf, sizeof(buf), false);
// got may be less than 1024
// Exact read
uint32_t length;
sock.readInto(&length, sizeof(length), true);
// Always reads exactly 4 bytes or throws

Implementation Details

  • Uses recv() internally for actual reads
  • Handles partial reads in exact mode
  • Buffer bounds checking
  • Platform-independent behavior
Parameters
[out]bufferPointer to caller-allocated memory buffer Must be valid and large enough for len bytes
[in]lenMaximum number of bytes to read (buffer size)
[in]exactIf true, method won't return until len bytes are read or an error occurs
Returns
Number of bytes actually read:
  • exact=false: 0 to len bytes
  • exact=true: Always len bytes or throws
Exceptions
SocketExceptionIf:
  • Socket is invalid (EBADF)
  • Connection closed by peer
  • Memory access error (EFAULT)
  • Timeout occurs (EAGAIN)
  • Other network errors
See also
read() Template method for type-safe reads
readUntil() For delimiter-based reading
readExact() For string-based exact reads

◆ readLine()

std::string jsocketpp::Socket::readLine ( const std::size_t maxLen = 8192,
const bool includeDelimiter = true )
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.

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Read a line terminated by newline
std::string line = sock.readLine();
// Read without including the newline
std::string data = sock.readLine(8192, false);
Parameters
[in]maxLenMaximum number of bytes to read (default: 8192)
[in]includeDelimiterWhether to include the newline in the returned string (default: true)
Returns
std::string containing the line read
Exceptions
SocketExceptionon error or if line exceeds maxLen
See also
readUntil() The underlying implementation
read() For general-purpose reading
readExact() For fixed-length reads

◆ readPrefixed() [1/2]

template<typename T>
std::string jsocketpp::Socket::readPrefixed ( )
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.

Implementation Details

  • First reads sizeof(T) bytes as the length prefix
  • Converts the prefix from network byte order to host byte order using net::fromNetwork()
  • Then reads exactly that many bytes as the payload
  • Length prefix must be a trivially copyable unsigned integral type (e.g., uint16_t, uint32_t)
  • Payload is returned as a std::string (binary-safe)

Example Usage

Socket sock("example.com", 8080);
sock.connect();
try {
// Read message with 32-bit length prefix
std::string msg = sock.readPrefixed<uint32_t>();
// Read message with 16-bit length prefix
std::string shortMsg = sock.readPrefixed<uint16_t>();
// Read multiple length-prefixed messages
while (sock.isConnected()) {
std::string data = sock.readPrefixed<uint32_t>();
process(data);
}
} catch (const SocketException& ex) {
// Handle read errors
}

Protocol Format

+----------------+----------------------+
| Length (T)     | Payload (n bytes)   |
+----------------+----------------------+
|<- sizeof(T) ->|<---- length ------->|
Template Parameters
TThe unsigned integral type used for the length prefix (e.g., uint32_t). Must be a trivially copyable type.
Returns
The payload as a std::string, excluding the length prefix.
Exceptions
SocketExceptionIf:
  • Connection is closed while reading
  • Length prefix is invalid/corrupt
  • Not enough data is available to complete the read
  • Memory allocation fails
  • Any network error occurs
Note
The prefix is assumed to be encoded in network byte order and is converted automatically to host byte order using jsocketpp::net::fromNetwork(). You must ensure that the sender uses the same byte ordering.
See also
read() For reading raw fixed-size values
readExact() For reading an exact number of bytes
writePrefixed() To send matching length-prefixed data
net::fromNetwork() For details on byte order conversion

◆ readPrefixed() [2/2]

template<typename T>
std::string jsocketpp::Socket::readPrefixed ( const std::size_t maxPayloadLen)
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().

Implementation Details

  • Reads sizeof(T) bytes as the length prefix
  • Converts the prefix from network byte order to host byte order
  • Throws an exception if the length exceeds maxPayloadLen
  • Reads exactly length bytes as the payload
  • Returns the payload as a binary-safe std::string

Example Usage

Socket sock("example.com", 8080);
sock.connect();
try {
std::string msg = sock.readPrefixed<uint32_t>(1024); // Rejects messages > 1024 bytes
process(msg);
} catch (const SocketException& ex) {
// Handle read errors
}

Protocol Format

+----------------+----------------------+
| Length (T)     | Payload (n bytes)   |
+----------------+----------------------+
|<- sizeof(T) ->|<---- length ------->|
Template Parameters
TThe unsigned integral type used for the length prefix (e.g., uint32_t). Must be a trivially copyable type.
Parameters
[in]maxPayloadLenMaximum allowed length of the decoded payload in bytes. If the decoded prefix exceeds this, an exception is thrown.
Returns
The payload as a std::string, excluding the length prefix.
Exceptions
SocketExceptionIf:
  • The connection is closed while reading
  • The length prefix is corrupt or invalid
  • The decoded length exceeds maxPayloadLen
  • Not enough data is available to fulfill the read
  • Memory allocation fails
  • Any network error occurs
Note
The prefix is automatically converted from network byte order to host byte order using jsocketpp::net::fromNetwork(). The sender must use the corresponding network encoding.
See also
read() For reading fixed-size types
readExact() For reading a known number of bytes
writePrefixed() For sending length-prefixed messages
net::fromNetwork() For byte order decoding

◆ readUntil()

std::string Socket::readUntil ( char delimiter,
std::size_t maxLen = 8192,
bool includeDelimiter = true )

Reads data from the socket until a specified delimiter character is encountered.

Reads and accumulates data from the socket until the given delimiter character is found, using the internal buffer for efficient, chunked recv() calls. Unlike byte-at-a-time reads, this method minimizes syscall overhead and improves performance by reading in larger blocks and scanning for the delimiter in memory.

If the delimiter is found, the method returns a string containing all bytes up to (and optionally including) the delimiter. If the delimiter is not found within maxLen bytes, an exception is thrown to prevent unbounded growth or protocol desynchronization.

Implementation Details

  • Uses _internalBuffer for buffered reads (size configurable via setInternalBufferSize())
  • Performs repeated recv() calls to fill the buffer and search for the delimiter
  • Tracks and accumulates received data until the delimiter is located
  • Supports truncation or inclusion of the delimiter via includeDelimiter
  • Throws on early connection close or delimiter absence beyond maxLen

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Read a line terminated by newline
std::string line = sock.readUntil('\n');
// Read CSV field terminated by comma
std::string field = sock.readUntil(',', 1024);
// Exclude the delimiter from the result
std::string text = sock.readUntil(';', 8192, false);
Parameters
[in]delimiterThe character to search for in the incoming data stream.
[in]maxLenThe maximum number of bytes to read before giving up (default: 8192).
[in]includeDelimiterWhether to include the delimiter in the returned string (default: true).
Returns
A std::string containing the data read up to the delimiter. The result includes the delimiter if includeDelimiter is set to true.
Exceptions
SocketExceptionIf:
  • The connection is closed before the delimiter is received
  • maxLen bytes are read without finding the delimiter
  • A network or system error occurs during reading
  • A configured timeout is exceeded (e.g., SO_RCVTIMEO)
  • The socket is invalid or in an error state
Note
This method is fully blocking unless a timeout is configured. Use readLine() as a newline-specific shorthand.
See also
readLine() For newline-terminated text input
readExact() For reading fixed-length binary data
read() For fixed-size or generic reads
setInternalBufferSize() To configure buffer size for bulk recv()
setSoRecvTimeout() To control read timeout duration

◆ readv()

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.

Example Usage

std::array<std::byte, 4> header;
std::array<std::byte, 128> payload;
std::array<BufferView, 2> views = {
BufferView{header.data(), header.size()},
BufferView{payload.data(), payload.size()}
};
std::size_t received = sock.readv(views);
Represents a raw writable memory region for scatter/gather I/O.
Definition BufferView.hpp:46
Parameters
[out]buffersA span of BufferView objects describing writable regions.
Returns
The total number of bytes read into the buffer sequence.
Exceptions
SocketExceptionIf:
  • The socket is invalid
  • recv() or readv() fails
  • Connection is closed prematurely
Note
This method performs a single recv()-style call. It does not retry. For full delivery into multiple buffers, use readvAll() (future).
See also
writev() For the write-side equivalent
readInto() For single-buffer reading

◆ readvAll()

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.

Example Usage

std::array<std::byte, 4> header;
std::vector<std::byte> payload(1024);
std::array<BufferView, 2> views = {
BufferView{header.data(), header.size()},
BufferView{payload.data(), payload.size()}
};
sock.readvAll(views);
Parameters
[out]buffersA span of writable buffer views to fill completely.
Returns
Total number of bytes read (equal to sum of buffer sizes).
Exceptions
SocketExceptionIf:
  • The connection is closed before all data is read
  • A system or network error occurs
Note
This is a high-level, blocking call. For partial reads, use readv().
See also
readv() For non-retrying variant

◆ readvAllWithTotalTimeout()

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 performs a series of vectorized readv() calls to fill the provided BufferView span until all bytes are read or the total timeout expires. A steady clock is used to measure elapsed time across multiple system calls, ensuring the full operation adheres to the timeout limit.

If not all data is read before the timeout elapses, a SocketTimeoutException is thrown.

Implementation Details

  • Performs repeated readv() calls into pending buffers.
  • Tracks time remaining using std::chrono::steady_clock.
  • Waits for readability before each attempt using waitReady().
  • Automatically handles partially filled buffers.

Example Usage

std::array<std::byte, 4> header;
std::vector<std::byte> payload(1024);
std::array<BufferView, 2> views = {
BufferView{header.data(), header.size()},
BufferView{payload.data(), payload.size()}
};
sock.readvAllWithTotalTimeout(views, 2000); // Must finish in 2 seconds
Parameters
[out]buffersSpan of BufferView objects describing writable memory regions.
[in]timeoutMillisMaximum allowed duration for the entire read operation, in milliseconds.
Returns
The total number of bytes read (must equal the sum of all buffer sizes on success).
Exceptions
SocketTimeoutExceptionIf:
  • Not all data is read before the timeout expires.
  • The socket does not become readable in time.
SocketExceptionIf:
  • readv() or recv() fails due to network error.
  • The socket is invalid or disconnected.
  • The connection is closed before all bytes are received.
Note
This method is fully blocking (until timeout or completion). Use readv() for a single read attempt, or readvAll() for a non-timed retry loop.
See also
readvAll() For retrying without a timeout
readv() For single-attempt best-effort vectorized reads
SocketTimeoutException For timeout-specific error handling

◆ readvAtMostWithTimeout()

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 milliseconds for the socket to become readable, then performs a single readv() operation into the provided buffer views. This method does not retry on partial reads and is suitable for polling-style I/O where responsiveness is more important than completeness.

May read fewer bytes than the total available buffer capacity, depending on what the socket delivers in a single system call. This is a timeout-aware variant of readv() and should be used when non-blocking responsiveness is desired.

Implementation Details

  • Calls waitReady() to wait for the socket to become readable.
  • Performs one readv() attempt only.
  • Reads whatever data is immediately available.
  • Returns early on connection closure or any received data.

Example Usage

std::array<std::byte, 8> header;
std::array<std::byte, 256> body;
std::array<BufferView, 2> bufs = {
BufferView{header.data(), header.size()},
BufferView{body.data(), body.size()}
};
std::size_t n = sock.readvAtMostWithTimeout(bufs, 300); // Wait up to 300 ms
std::cout << "Received " << n << " bytes.\n";
Parameters
[out]buffersSpan of writable BufferViews to receive incoming data.
[in]timeoutMillisTime in milliseconds to wait for readability:
  • > 0: Wait up to this duration
  • 0: Non-blocking (poll)
  • < 0: Invalid; throws exception
Returns
Number of bytes read (may be 0 if timeout is 0 or nothing available).
Exceptions
SocketTimeoutExceptionIf the socket does not become readable before timeout.
SocketExceptionIf:
  • readv() fails with a system/network error
  • The socket is invalid
  • The connection is closed
Note
This method performs a single system call. It does not retry or block for more data.
See also
readv() For non-timed scatter read
readvAllWithTotalTimeout() For complete delivery within a time budget
SocketTimeoutException For timeout-related error details

◆ resetShutdownFlags()

void jsocketpp::Socket::resetShutdownFlags ( )
inlineprotectednoexcept

Resets internal shutdown state flags to false.

This method clears the internal flags that track whether the socket's input or output streams have been shutdown via shutdown(ShutdownMode). It does not reopen or re-enable socket directions at the system level—it only resets the internal state used by isInputShutdown() and isOutputShutdown().

This method is useful when reinitializing or repurposing a Socket object after calling close(), or when transferring ownership during a move assignment where shutdown state is no longer valid.

Warning
This method does not call any OS-level functions like shutdown() or setsockopt(). It only resets internal bookkeeping flags.
Note
This method is intended for internal use or advanced scenarios. Most users should not need to call this directly.
See also
shutdown()
isInputShutdown()
isOutputShutdown()

◆ resolveBuffers()

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
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.

Parameters
recvOptional receive buffer size.
sendOptional send buffer size.
internalOptional internal buffer size.
Returns
A tuple: {resolvedRecvBufferSize, resolvedSendBufferSize, resolvedInternalBufferSize}
See also
getEffectiveReceiveBufferSize()
getEffectiveSendBufferSize()

◆ ServerSocket() [1/4]

jsocketpp::ServerSocket::ServerSocket ( )
delete

Default constructor (deleted) for ServerSocket class.

The default constructor is explicitly deleted to prevent the creation of uninitialized ServerSocket objects. Each server socket must be explicitly constructed with a valid port and configuration parameters to ensure correct binding and listening behavior.

Rationale

  • Prevents creation of non-functional server sockets
  • Enforces proper initialization with port, backlog, and reuse options
  • Ensures RAII ownership over system-level resources
ServerSocket s; // ❌ Compilation error (deleted constructor)
ServerSocket s(8080); // ✅ Valid usage: bind to port 8080
See also
ServerSocket(Port, std::string_view, bool, bool, int, bool) Primary constructor

◆ ServerSocket() [2/4]

jsocketpp::ServerSocket::ServerSocket ( const ServerSocket & rhs)
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.

Parameters
[in]rhsThe ServerSocket to copy from (unused since deleted).
Note
This deletion helps prevent accidental copying of socket resources and enforces RAII principles.
See also
ServerSocket(ServerSocket&&)
operator=(ServerSocket&&)

◆ ServerSocket() [3/4]

ServerSocket::ServerSocket ( Port port,
std::string_view localAddress = {},
bool autoBindListen = true,
bool reuseAddress = true,
int soTimeoutMillis = -1,
bool dualStack = true )
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:

  • Prepares address resolution hints for dual-stack TCP sockets (IPv4 and IPv6).
  • Uses getaddrinfo() to resolve the provided localAddress (IP address or hostname) and the given port.
    • If localAddress is empty ({}), the socket will accept connections on ALL local interfaces.
    • If non-empty, binds only to the specified address/interface (e.g., "127.0.0.1", "::1", "192.168.1.10").
  • Iterates through the address results, attempting to create a socket for each until one succeeds.
  • For IPv6 sockets, configures dual-stack or IPv6-only mode according to the dualStack parameter:
    • If dualStack is true (default), disables IPV6_V6ONLY for dual-stack support (accepts both IPv4 and IPv6).
    • If dualStack is false, enables IPV6_V6ONLY for IPv6-only operation (no IPv4-mapped addresses).
  • Sets the address reuse option (reuseAddress) before binding:
    • On Windows, uses SO_EXCLUSIVEADDRUSE (for exclusive binding).
    • On Unix-like systems, uses SO_REUSEADDR (for fast port reuse).
  • If autoBindListen is true, automatically calls bind() and listen() (with default backlog). Otherwise, you must call them manually after construction.
  • Sets the accept timeout (soTimeoutMillis) for all subsequent accept() operations.
Note
  • If you want to fine-tune socket options (e.g., reuse, timeouts) or bind on demand, use autoBindListen = false and set options before calling bind() and listen().
  • The final reuse address setting is determined by the last value set before bind() (either by parameter or setReuseAddress()).
  • Once bound, further changes to address reuse have no effect.
  • The timeout applies to all accept() and tryAccept() calls unless a per-call timeout is provided.
  • For maximum compatibility with both IPv4 and IPv6 clients, use an empty localAddress and default settings.
  • Dual-stack mode is only relevant for IPv6 sockets. On platforms or addresses that do not support dual-stack, the dualStack parameter may be ignored.
This constructor is not thread safe. Do not share a ServerSocket instance between threads during construction.
Parameters
[in]portThe port number to prepare the server socket for (binding will occur according to autoBindListen).
[in]localAddressThe local address/interface to bind to (empty for all interfaces).
[in]autoBindListenIf true (default), automatically binds and listens. If false, user must call them manually.
[in]reuseAddressIf true (default), enables address reuse (see above) before binding.
[in]soTimeoutMillisAccept timeout in milliseconds for accept(); -1 (default) means block indefinitely.
[in]dualStackIf 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.
Exceptions
SocketExceptionIf address resolution, socket creation, binding, or socket option configuration fails.
See also
setReuseAddress(), setSoTimeout(), bind(), listen(), accept()
// Example: Minimal usage—listen on all interfaces, default options
// Example: Listen on all interfaces, enable address reuse, block up to 5 seconds for accept()
jsocketpp::ServerSocket server(8080, {}, true, true, 5000);
// Example: Manual control—bind and listen later
jsocketpp::ServerSocket server(8080, "127.0.0.1", false, false);
server.setReuseAddress(true); // Change before bind
server.bind();
server.listen();
// Example: IPv6-only server (no IPv4-mapped addresses)
jsocketpp::ServerSocket server(8080, "::1", true, true, -1, false);

◆ ServerSocket() [4/4]

jsocketpp::ServerSocket::ServerSocket ( ServerSocket && rhs)
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:

  • All resources are transferred from rhs to the new object.
  • The moved-from object (rhs) is left in a valid but empty state.
  • No system resources are duplicated or leaked during the transfer.

After the move:

  • The new object takes full ownership of the socket and its state.
  • The moved-from object becomes closed (invalid socket, null pointers).
  • All socket options and state flags are transferred.
Parameters
[in]rhsThe ServerSocket to move resources from.
Note
This operation is thread-safe with respect to the moved-from socket, but concurrent operations on either socket during the move may cause undefined behavior.
See also
operator=(ServerSocket&&)
close()

◆ setDefaultInternalBufferSize()

void jsocketpp::ServerSocket::setDefaultInternalBufferSize ( const std::size_t size)
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).

Parameters
sizeNew default buffer size in bytes for this socket/server instance.
See also
getDefaultInternalBufferSize()
getEffectiveInternalBufferSize()
DefaultBufferSize

◆ setDefaultReceiveBufferSize()

void jsocketpp::ServerSocket::setDefaultReceiveBufferSize ( const std::size_t size)
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.

Note
Thread-safe if called before concurrent accept() calls.
Parameters
[in]sizeNew buffer size in bytes
See also
getDefaultReceiveBufferSize()
DefaultBufferSize
accept(), acceptBlocking(), tryAccept()

◆ setDefaultSendBufferSize()

void jsocketpp::ServerSocket::setDefaultSendBufferSize ( const std::size_t size)
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.

Note
Thread-safe if called before concurrent accept() calls.
Parameters
[in]sizeNew send buffer size in bytes
See also
getDefaultSendBufferSize()
DefaultBufferSize
accept()

◆ setInternalBufferSize()

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).

Purpose

  • Controls maximum size of data readable in one read<std::string>() call
  • Affects memory usage of the Socket object
  • Does not affect system socket buffers or network behavior

Implementation Details

  • Resizes internal std::vector<char> buffer
  • Used only for string-based reads
  • Not used for fixed-size read<T>() operations
  • Thread-safe with respect to other Socket instances

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Set 8KB internal buffer for string reads
sock.setInternalBufferSize(8192);
// Read will now use 8KB buffer
std::string data = sock.read<std::string>();
Parameters
[in]newLenNew size for the internal buffer in bytes
Exceptions
std::bad_allocIf memory allocation fails
See also
setReceiveBufferSize() For setting the OS socket receive buffer
read<std::string>() Uses this buffer for string operations
setSendBufferSize() For setting the OS socket send buffer

◆ shutdown()

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.

Shutdown Modes

  • ShutdownMode::Read: Disables further receive operations
    • Subsequent read() calls will return EOF
    • Already received data can still be read
    • Send operations remain unaffected
  • ShutdownMode::Write: Disables further send operations
    • Sends pending data before shutting down
    • Sends FIN packet to peer
    • Receive operations remain unaffected
  • ShutdownMode::Both: Disables both send and receive operations (full-duplex shutdown)
    • Equivalent to calling shutdown() with Read and Write modes
    • Unlike close(), this does not release the socket descriptor or system resources.
    • The socket remains open and can still be queried, reused, or closed later.

Example Usage

Socket sock("example.com", 80);
sock.connect();
// Send final message
sock.write("Goodbye!");
// Shutdown sending but continue receiving
sock.shutdown(ShutdownMode::Write);
// Read any remaining responses
std::string response = sock.read<std::string>();
// Complete shutdown
sock.shutdown(ShutdownMode::Both);
@ Write
Shutdown write operations (SHUT_WR or SD_SEND).
Definition common.hpp:371
@ Both
Shutdown both read and write operations (SHUT_RDWR or SD_BOTH).
Definition common.hpp:372

Implementation Details

  • Uses platform-specific shutdown() system call
  • Handles partial shutdowns gracefully
  • Does not release socket resources (use close() for that)
  • Socket remains valid after shutdown
Parameters
[in]howSpecifies which operations to shut down:
Exceptions
SocketExceptionIf:
  • Socket is invalid (EBADF)
  • Socket is not connected (ENOTCONN)
  • Permission denied (EACCES)
  • Memory/resource allocation fails
  • Other system-specific errors
Note
This method is not thread-safe. Do not call shutdown() while other threads are performing operations on the same Socket instance.
See also
close() For completely closing the socket
isConnected() Check connection status
ShutdownMode Enumeration of available shutdown modes

◆ Socket() [1/5]

jsocketpp::Socket::Socket ( )
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.

Rationale

  • Prevents accidental creation of an invalid socket
  • Enforces explicit resource ownership and initialization
  • Avoids ambiguity around object state (e.g., getSocketFd() = INVALID_SOCKET)
Socket s; // ❌ Compilation error (deleted constructor)
Socket s("host", 1234); // ✅ Correct usage
See also
Socket(std::string_view, Port, std::size_t) Primary constructor
Socket(SOCKET, const sockaddr_storage&, socklen_t, std::size_t, std::size_t) Server-side accept constructor

◆ Socket() [2/5]

jsocketpp::Socket::Socket ( const Socket & rhs)
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:

  • Double-closing of socket descriptors
  • Race conditions in multi-threaded code
  • Ambiguous ownership of system resources
  • Potential resource leaks

Instead of copying, use move semantics (Socket&&) to transfer ownership of a Socket from one object to another. For example:

Socket s1("example.com", 80);
Socket s2(std::move(s1)); // OK: moves ownership from s1 to s2
Socket s3(s2); // Error: copying is disabled
Parameters
[in]rhsThe Socket object to copy from (unused since deleted)
See also
Socket(Socket&&) Move constructor for transferring socket ownership
operator=(Socket&&) Move assignment operator for transferring socket ownership

◆ Socket() [3/5]

jsocketpp::Socket::Socket ( Socket && rhs)
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:

  1. Takes ownership of the socket descriptor
  2. Transfers remote address information
  3. Moves address resolution data
  4. Transfers the receive buffer
  5. Resets the source object to a valid but empty state

The moved-from socket (rhs) remains valid but will be in a default-constructed state with no active connection (getSocketFd() = INVALID_SOCKET).

Parameters
[in,out]rhsThe Socket object to move from. After the move, rhs will be left in a valid but disconnected state.
Note
This operation is noexcept as it cannot fail - at worst, we'd have a Socket in an empty state, which is valid.
See also
Socket(const Socket&) Copy constructor (deleted)
operator=(Socket&&) Move assignment operator

◆ Socket() [4/5]

Socket::Socket ( SOCKET client,
const sockaddr_storage & addr,
socklen_t len,
std::size_t recvBufferSize = DefaultBufferSize,
std::size_t sendBufferSize = DefaultBufferSize,
std::size_t internalBufferSize = DefaultBufferSize,
int soRecvTimeoutMillis = -1,
int soSendTimeoutMillis = -1,
bool tcpNoDelay = true,
bool keepAlive = false,
bool nonBlocking = false )
protected

Wraps an accepted TCP client socket with optional tuning parameters.

This constructor creates a Socket object by taking ownership of a socket descriptor returned by accept(), applying the given address, and configuring buffer sizes, timeouts, and TCP-specific options.


🛠 Use Cases

  • Inside ServerSocket::accept() to wrap the raw socket handle into a high-level object
  • For servers that need to apply consistent socket-level behavior (timeouts, no-delay, etc.)
  • For applications using RAII and exception-safe socket wrappers

Configuration Parameters

  • recvBufferSize, sendBufferSize: OS-level socket buffers (SO_RCVBUF, SO_SNDBUF)
  • internalBufferSize: Buffer used by read<T>() and read<std::string>()
  • soRecvTimeoutMillis: Read timeout in milliseconds (SO_RCVTIMEO)
  • soSendTimeoutMillis: Send timeout in milliseconds (SO_SNDTIMEO)
  • tcpNoDelay: Disables Nagle's algorithm (TCP_NODELAY) for low-latency use cases
  • keepAlive: Enables TCP keep-alive (SO_KEEPALIVE)
  • nonBlocking: Places the socket in non-blocking mode immediately after construction

🧠 Example

ServerSocket server(8080);
3000, 1000, true, true, false);
constexpr std::size_t DefaultBufferSize
Default internal buffer size (in bytes) for socket read operations.
Definition common.hpp:434
friend class ServerSocket
Grants ServerSocket access to private members.
Definition Socket.hpp:107

Parameters
[in]clientA connected socket descriptor returned by accept()
[in]addrThe client's address information (from accept())
[in]lenLength of the address structure
[in]recvBufferSizeOS-level receive buffer size
[in]sendBufferSizeOS-level send buffer size
[in]internalBufferSizeInternal read buffer size
[in]soRecvTimeoutMillisTimeout for recv()/read() in milliseconds; -1 disables
[in]soSendTimeoutMillisTimeout for send() in milliseconds; -1 disables
[in]tcpNoDelayWhether to disable Nagle's algorithm
[in]keepAliveWhether to enable TCP keep-alive
[in]nonBlockingWhether to set the socket to non-blocking mode
Exceptions
SocketExceptionIf any tuning operation fails after the socket is accepted
See also
ServerSocket::accept(), setSoRecvTimeout(), setSoSendTimeout(), setTcpNoDelay(), setNonBlocking()

◆ Socket() [5/5]

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,
bool reuseAddress = true,
int soRecvTimeoutMillis = -1,
int soSendTimeoutMillis = -1,
bool dualStack = true,
bool tcpNoDelay = true,
bool keepAlive = false,
bool nonBlocking = false,
bool autoConnect = true,
bool autoBind = false,
std::string_view localAddress = "",
Port localPort = 0 )

Constructs a TCP client socket, resolves the remote host and port, and optionally binds or connects.

This constructor creates a TCP socket intended for client-side connections. It resolves the specified remote host and port, applies socket-level configuration, and optionally:

  • Binds the socket to a specified local address and/or port (autoBind)
  • Connects to the resolved peer (autoConnect)

The socket supports both IPv4 and IPv6, dual-stack operation, and high-level configuration of timeouts, buffer sizes, and TCP flags like TCP_NODELAY and SO_KEEPALIVE.


🔧 Configuration Parameters

  • recvBufferSize, sendBufferSize: Set OS-level buffer sizes (SO_RCVBUF, SO_SNDBUF)
  • internalBufferSize: Controls the internal buffer used by high-level read methods
  • reuseAddress: Enables SO_REUSEADDR, useful for NAT traversal and reconnect loops
  • soRecvTimeoutMillis: Sets read timeout in milliseconds (SO_RCVTIMEO); -1 disables
  • soSendTimeoutMillis: Sets send timeout in milliseconds (SO_SNDTIMEO); -1 disables
  • dualStack: Enables dual-stack fallback via AF_UNSPEC (IPv6 socket accepts IPv4-mapped traffic)
  • tcpNoDelay: Disables Nagle's algorithm (TCP_NODELAY) for low-latency protocols
  • keepAlive: Enables TCP keep-alive probes (SO_KEEPALIVE)
  • nonBlocking: Sets the socket to non-blocking mode immediately after creation
  • autoBind: If true, binds to the specified local address and/or port before connecting
  • autoConnect: If true, performs a blocking connect() immediately after creation

🌐 Local Binding Parameters (used only if autoBind == true)

  • localAddress: IP address to bind from (e.g., "192.168.0.100" or "::1"). Use empty string to bind to all local interfaces.
  • localPort: Port to bind from. Use 0 to let the OS assign an ephemeral port.

🧠 Example

Socket sock("api.example.com", 443,
8192, 8192, 8192,
true, // reuseAddress
5000, // soRecvTimeoutMillis
2000, // soSendTimeoutMillis
true, // dualStack
true, // tcpNoDelay
true, // keepAlive
false, // nonBlocking
true, // autoConnect
true, // autoBind
"192.168.1.10", // localAddress
0); // localPort

Parameters
[in]hostRemote hostname or IP address to connect to
[in]portRemote TCP port number
[in]recvBufferSizeOptional socket receive buffer size (SO_RCVBUF)
[in]sendBufferSizeOptional socket send buffer size (SO_SNDBUF)
[in]internalBufferSizeOptional internal read buffer size for high-level operations
[in]reuseAddressEnables SO_REUSEADDR to allow rebinding to the same port
[in]soRecvTimeoutMillisTimeout for receive operations in milliseconds (SO_RCVTIMEO)
[in]soSendTimeoutMillisTimeout for send operations in milliseconds (SO_SNDTIMEO)
[in]dualStackIf true, uses AF_UNSPEC to allow IPv6+IPv4 fallback
[in]tcpNoDelayIf true, disables Nagle’s algorithm (TCP_NODELAY)
[in]keepAliveIf true, enables TCP keep-alive probes
[in]nonBlockingIf true, sets the socket to non-blocking mode after creation
[in]autoConnectIf true, immediately performs a blocking connect() to the peer
[in]autoBindIf true, performs a bind() before connecting
[in]localAddressLocal IP to bind to (if autoBind == true)
[in]localPortLocal port to bind to (if autoBind == true)
Exceptions
SocketExceptionIf resolution, socket creation, binding, configuration, or connection fails
See also
connect(), bind(), setSoRecvTimeout(), setSoSendTimeout(), setTcpNoDelay(), setNonBlocking()

◆ tryAccept() [1/2]

std::optional< Socket > 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,
int soRecvTimeoutMillis = -1,
int soSendTimeoutMillis = -1,
bool tcpNoDelay = true,
bool keepAlive = false,
bool nonBlocking = false ) const
nodiscard

Attempt to accept an incoming client connection, waiting up to a specified timeout and returning std::nullopt on timeout.

This method waits for an incoming client connection using the explicitly provided timeoutMillis value, overriding any timeout configured via setSoTimeout(). If a client connects before the timeout expires, a fully configured Socket is returned. Otherwise, std::nullopt is returned instead of throwing.


⏱ Timeout Behavior

  • Negative timeoutMillis: Block indefinitely until a client connects
  • Zero: Poll immediately; return std::nullopt if no client is waiting
  • Positive: Wait up to timeoutMillis milliseconds; return std::nullopt if no client connects in time

Readiness is detected using select() via waitReady(timeoutMillis), followed by a call to acceptBlocking(...) if the socket is ready.


⚙️ Configuration of Accepted Socket

If a client is accepted, the resulting Socket is configured using the following options:

  • recvBufferSize, sendBufferSize: OS-level socket buffer sizes (SO_RCVBUF, SO_SNDBUF)
  • internalBufferSize: High-level internal buffer used by read<T>() and read<std::string>()
  • soRecvTimeoutMillis: Socket receive timeout (SO_RCVTIMEO) in milliseconds
  • soSendTimeoutMillis: Socket send timeout (SO_SNDTIMEO) in milliseconds
  • tcpNoDelay: Disables Nagle’s algorithm (TCP_NODELAY) for low-latency operation (default: true)
  • keepAlive: Enables TCP keep-alive probes (SO_KEEPALIVE)
  • nonBlocking: If true, sets the accepted socket to non-blocking mode

⚠️ Race Condition Warning

Even after readiness is reported, accept() may still fail with EWOULDBLOCK or EAGAIN if the client disconnects in the small window before accept() is invoked. In that case, a SocketException is thrown.


⚠️ Thread Safety

This method is not thread-safe. If used from multiple threads, you must externally synchronize access to the server socket to prevent race conditions.


🧠 Example

ServerSocket server(8080);
server.bind();
server.listen();
while (true) {
auto client = server.tryAccept(100, // Wait 100 ms per poll
8192, 8192, 8192, // Buffer sizes
3000, 1000, // Timeouts
true, true, false); // Tuning flags
if (client) {
handleClient(*client);
} else {
// No client yet — continue polling
}
}

Parameters
[in]timeoutMillisTimeout in milliseconds for this call:
  • Negative: block indefinitely
  • Zero: poll once
  • Positive: wait up to timeoutMillis for a connection
[in]recvBufferSizeOptional receive buffer size (SO_RCVBUF)
[in]sendBufferSizeOptional send buffer size (SO_SNDBUF)
[in]internalBufferSizeOptional internal buffer for read<T>()-style calls
[in]soRecvTimeoutMillisReceive timeout for the accepted socket (SO_RCVTIMEO); -1 disables
[in]soSendTimeoutMillisSend timeout for the accepted socket (SO_SNDTIMEO); -1 disables
[in]tcpNoDelayWhether to disable Nagle’s algorithm (TCP_NODELAY); default: true
[in]keepAliveWhether to enable TCP keep-alive (SO_KEEPALIVE)
[in]nonBlockingWhether to set the accepted socket to non-blocking mode
Returns
std::optional<Socket> — configured client socket on success, or std::nullopt on timeout
Exceptions
SocketExceptionIf the server socket is invalid or accept() fails due to system error
Precondition
The server socket must be open, bound, and listening
Postcondition
Returns a valid Socket or std::nullopt if the timeout expires
See also
tryAccept(), accept(), acceptBlocking(), acceptNonBlocking(), waitReady(), setSoTimeout()

◆ tryAccept() [2/2]

std::optional< Socket > 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,
int soRecvTimeoutMillis = -1,
int soSendTimeoutMillis = -1,
bool tcpNoDelay = true,
bool keepAlive = false,
bool nonBlocking = false ) const
nodiscard

Attempt to accept an incoming client connection, returning std::nullopt on timeout instead of throwing.

This method waits for an incoming client connection using the timeout configured via setSoTimeout(). If a client is available before the timeout expires, it returns a fully configured Socket object. If no client connects in time, it returns std::nullopt rather than throwing.


⏱ Timeout Behavior

  • If the socket timeout is negative (default), the method blocks indefinitely.
  • If the timeout is zero, it polls and returns immediately if no client is waiting.
  • If the timeout is positive, the method waits up to that many milliseconds using select().
    • If no connection arrives within that time, it returns std::nullopt (unlike accept() which throws).

Internally, waitReady() is used for readiness detection, followed by acceptBlocking() for the actual accept.


⚙️ Configuration of Accepted Socket

The returned Socket (if any) is configured using the following tuning options:

  • recvBufferSize, sendBufferSize: OS-level buffer sizes (SO_RCVBUF, SO_SNDBUF)
  • internalBufferSize: Internal buffer used by read<T>() and read<std::string>()
  • soRecvTimeoutMillis: Receive timeout for the socket (SO_RCVTIMEO) in milliseconds
  • soSendTimeoutMillis: Send timeout for the socket (SO_SNDTIMEO) in milliseconds
  • tcpNoDelay: Disables Nagle’s algorithm for lower latency (default: true)
  • keepAlive: Enables TCP keep-alive probes
  • nonBlocking: Immediately sets the accepted socket into non-blocking mode

⚠️ Thread Safety

This method is not thread-safe. Concurrent calls from multiple threads or processes may cause race conditions or spurious failures. Use a mutex to guard access to accept() methods if needed.


💡 Notes

  • This method is ideal for polling servers and event-driven architectures.
  • For per-call timeouts instead of using setSoTimeout(), use tryAccept(int timeoutMillis, ...).
  • Unlike accept(), this method never throws SocketTimeoutException.

🧠 Example

ServerSocket server(8080);
server.bind();
server.listen();
server.setSoTimeout(100); // Poll every 100 ms
while (true) {
if (auto client = server.tryAccept(
8192, 8192, 8192,
3000, 1000,
true, true, false)) {
handleClient(*client);
} else {
// No client ready; do other work
}
}

Parameters
[in]recvBufferSizeOptional socket receive buffer size (SO_RCVBUF)
[in]sendBufferSizeOptional socket send buffer size (SO_SNDBUF)
[in]internalBufferSizeOptional internal buffer for high-level reads
[in]soRecvTimeoutMillisReceive timeout (SO_RCVTIMEO) in milliseconds; -1 disables
[in]soSendTimeoutMillisSend timeout (SO_SNDTIMEO) in milliseconds; -1 disables
[in]tcpNoDelayWhether to disable Nagle’s algorithm (TCP_NODELAY); default: true
[in]keepAliveWhether to enable TCP keep-alive (SO_KEEPALIVE)
[in]nonBlockingWhether to set the accepted socket to non-blocking mode
Returns
std::optional<Socket> — a connected and configured Socket on success, or std::nullopt on timeout
Exceptions
SocketExceptionif the server socket is invalid or accept() fails for other reasons
Precondition
Server socket must be valid, bound, and listening
Postcondition
Returns std::nullopt if no client connects in time, or a valid Socket if one does
See also
setSoTimeout(), getSoTimeout(), tryAccept(int), accept(), acceptBlocking(), waitReady()

◆ waitReady() [1/2]

bool ServerSocket::waitReady ( std::optional< int > timeoutMillis = std::nullopt) const
nodiscard

Waits for the server socket to become ready to accept an incoming connection.

This method blocks or polls until the server socket becomes readable, indicating that a new client is attempting to connect. It is used internally by accept() and tryAccept(), but can also be used directly in custom event loops or multiplexed servers.

Platform Behavior

  • POSIX: Uses poll() to monitor readiness, avoiding the FD_SETSIZE constraint imposed by select().
  • Windows: Uses select() to ensure compatibility with all socket types.
    • The socket descriptor must be less than FD_SETSIZE (typically 64 on Windows).
    • If the descriptor exceeds FD_SETSIZE, a SocketException is thrown to prevent undefined behavior.

Timeout Semantics

  • timeoutMillis < 0: Blocks indefinitely until a connection attempt is ready.
  • timeoutMillis == 0: Performs a non-blocking poll and returns immediately.
  • timeoutMillis > 0: Waits up to the specified number of milliseconds.
  • If timeoutMillis is not provided, the socket's logical timeout (_soTimeoutMillis) is used.
Note
This method does not rely on or modify kernel-level timeouts (e.g., SO_RCVTIMEO). It uses event polling (poll() or select()) for logical timeout behavior.

Thread Safety

This method is thread-safe as long as the server socket is not concurrently closed or reconfigured.

Parameters
[in]timeoutMillisOptional timeout in milliseconds. If omitted, the socket's SO_TIMEOUT is used.
Returns
true if the socket is ready to accept a connection, false if the timeout expired.
Exceptions
SocketExceptionif:
  • The server socket is not initialized (INVALID_SOCKET)
  • A system-level polling error occurs
  • The socket descriptor exceeds platform limits (FD_SETSIZE) on Windows
See also
accept() Accepts a new incoming connection
tryAccept() Non-blocking variant of accept()
setSoTimeout() Sets the default timeout used by this method
getSoTimeout() Retrieves the current logical timeout value

◆ waitReady() [2/2]

bool Socket::waitReady ( bool forWrite,
int timeoutMillis ) const

Waits for the socket to become ready for reading or writing.

This method performs a blocking or timed wait until the socket is ready for either reading or writing, depending on the forWrite parameter. Internally, it uses the select() system call to monitor readiness.

The timeout is specified in milliseconds. A negative timeout value (e.g., -1) causes the method to wait indefinitely until the socket becomes ready. A timeout of 0 performs a non-blocking poll.

Implementation Notes

  • Internally uses select() on both POSIX and Windows platforms.
  • On POSIX, the socket descriptor must be less than FD_SETSIZE (typically 1024). If the descriptor exceeds this limit, a SocketException is thrown.
  • On Windows, the first parameter to select() is ignored and always set to 0.
  • This method works for both blocking and non-blocking sockets.

Example

Socket sock("example.com", 8080);
sock.connect();
if (sock.waitReady(false, 5000)) {
std::string msg = sock.read<std::string>();
std::cout << "Received: " << msg << "\\n";
}

Protocol Behavior

  • forWrite == false: Waits for the socket to be readable (e.g., data available).
  • forWrite == true: Waits for the socket to be writable (e.g., buffer space available).
Parameters
[in]forWriteIf true, waits for the socket to become writable; if false, waits for it to be readable.
[in]timeoutMillisTimeout in milliseconds. Use -1 for infinite wait, or 0 for non-blocking polling.
Return values
trueThe socket is ready for I/O.
falseThe timeout expired before the socket became ready.
Exceptions
SocketExceptionIf:
  • The socket is invalid (INVALID_SOCKET)
  • The socket descriptor exceeds FD_SETSIZE (POSIX only)
  • A system error occurs during polling
Note
This method uses the legacy select() system call, which is portable but has limitations:
  • On POSIX systems, it cannot monitor descriptors ≥ FD_SETSIZE (usually 1024)
  • fd_set is a static bitset, and overflow causes undefined behavior
  • select() scales poorly with large socket sets

    Alternatives:
  • On POSIX: poll() (removes FD_SETSIZE limit, cleaner API)
  • On Linux: epoll (scales to thousands of fds)
  • On BSD/macOS: kqueue (efficient and feature-rich)
  • On Windows: WSAPoll() (requires Windows Vista+), or I/O Completion Ports for async

    These alternatives are better suited for server-side multiplexing and event-driven designs. For single-socket or per-connection waiting, select() remains simple and widely compatible.
See also
setBlocking() To configure blocking/non-blocking mode
read() For reading data once the socket is ready
write() For writing data once the socket is ready
FD_SETSIZE System-defined maximum descriptor index for select()

◆ write()

size_t Socket::write ( std::string_view message) const
nodiscard

Sends data to the socket using a single, best-effort write operation.

Attempts to write up to message.size() bytes from the given std::string_view to the connected socket. This method may return before all data is sent, depending on socket state, system buffer availability, and platform behavior. It performs exactly one send() call and does not retry if the write is partial.

This is the fundamental low-level output method. For complete delivery guarantees, use writeAll() or writeWithTotalTimeout() instead.

Implementation Details

  • Performs a single call to send() (platform-specific: send() or send_s() on Windows)
  • Supports binary data, including embedded null bytes (\0)
  • Returns the number of bytes actually written (may be less than message.size())
  • This method does not retry; for guaranteed delivery use writeAll().

Example Usage

Socket sock("example.com", 80);
sock.connect();
std::string payload = "POST /data HTTP/1.1\r\n\r\n";
std::size_t sent = sock.write(payload);
if (sent < payload.size()) {
std::cerr << "Partial write: sent " << sent << " of " << payload.size() << " bytes\n";
// Handle retries or buffering as needed
}
Parameters
[in]messageThe data to send. Can contain binary content, including null characters.
Returns
The number of bytes actually written to the socket. May be less than message.size() for partial writes.
Exceptions
SocketExceptionIf:
  • The socket is invalid, closed, or unconnected (ENOTCONN, EBADF)
  • A network error occurs (ECONNRESET, ENETDOWN, EPIPE)
  • The operation would block on a full buffer in non-blocking mode (EWOULDBLOCK)
  • A system-level error occurs (EINTR, EINVAL, etc.)
Note
[[nodiscard]] is applied to enforce that the return value must be checked. Ignoring the result may lead to silent data loss if only part of the data was sent. Always compare against message.size() to detect partial delivery.
See also
writeAll() For guaranteed delivery via retries
writeWithTotalTimeout() For deadline-bounded full writes
writeFrom() For zero-copy buffer-based sending
writev() For vectorized scatter/gather writes
setNonBlocking() To configure non-blocking socket behavior
setSoSendTimeout() To configure write timeouts

◆ writeAll()

size_t Socket::writeAll ( std::string_view message) const

Writes the entire contents of a message to the socket, retrying as needed.

Ensures that the entire message is transmitted by repeatedly invoking the low-level write() method to handle partial writes. This method blocks until all data is successfully sent, the connection is lost, or an error occurs. It is suitable for protocols or data formats that require full delivery of fixed-size payloads, headers, or serialized objects.

Unlike write(), which may send only part of the input in a single call, this method transparently retries until all bytes are written, making it reliable for complete transmission scenarios (e.g., HTTP requests, framed packets, serialized data).

Implementation Details

  • Uses write() internally for each chunk
  • Tracks remaining bytes and offset for partial sends
  • Retries automatically until message.size() bytes are sent
  • Blocks if necessary (unless socket is configured as non-blocking)
  • Binary-safe: supports null bytes and non-text data

Example Usage

Socket sock("example.com", 80);
sock.connect();
std::string msg = "POST /data HTTP/1.1\r\nContent-Length: 42\r\n\r\n...";
try {
std::size_t sent = sock.writeAll(msg);
std::cout << "Successfully sent all " << sent << " bytes\n";
} catch (const SocketException& ex) {
std::cerr << "Failed to send full message: " << ex.what() << '\n';
}
Parameters
[in]messageThe message to send in full. May contain binary or textual content.
Returns
The total number of bytes written. Will always equal message.size() on success.
Exceptions
SocketExceptionIf:
  • The socket is invalid or not connected (ENOTCONN, EBADF)
  • The connection is closed during transmission
  • A network error occurs (ECONNRESET, ENETDOWN, EPIPE, etc.)
  • A socket timeout is triggered (SO_SNDTIMEO)
  • A system-level failure interrupts transmission
Note
This method will block until all data is sent or an error/timeout occurs. For non-blocking or time-bounded writes, use writeWithTotalTimeout().
See also
write() For a single-attempt best-effort write
writeWithTotalTimeout() For full delivery under time constraints
setSoSendTimeout() To configure write timeouts
setNonBlocking() To avoid blocking behavior
isConnected() To check socket status before writing

◆ writeAtMostWithTimeout()

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 milliseconds for the socket to become writable, then attempts a single send() operation to write up to data.size() bytes. This method does not retry on partial writes and is designed for time-sensitive, latency-focused applications.

This is a timeout-aware counterpart to write() that returns early in the event of timeout or connection closure. Use this when you need responsiveness rather than guaranteed delivery.

Implementation Details

  • Calls waitReady(true, timeoutMillis) to wait for socket writability.
  • If writable, performs one send() call.
  • Returns the number of bytes successfully written (which may be less than data.size()).
  • Returns 0 if the connection is closed before any data is written.

Example Usage

std::string payload = "POST /data";
try {
std::size_t sent = sock.writeAtMostWithTimeout(payload, 500); // wait up to 500 ms
std::cout << "Sent " << sent << " bytes.\n";
} catch (const SocketTimeoutException& e) {
std::cerr << "Write timed out: " << e.what() << std::endl;
} catch (const SocketException& e) {
std::cerr << "Write error: " << e.what() << std::endl;
}
Parameters
[in]dataThe data to send.
[in]timeoutMillisMaximum time to wait for writability, in milliseconds:
  • > 0: Wait up to the given duration
  • 0: Poll immediately (non-blocking)
  • < 0: Invalid; throws exception
Returns
Number of bytes written (may be 0 if the socket was closed or data not sent).
Exceptions
SocketTimeoutExceptionIf the socket does not become writable within timeoutMillis.
SocketExceptionIf:
  • send() fails with a network or system error
  • The socket is closed or invalid
Note
This is a single-attempt, low-latency write. Use writeAll() or writeWithTotalTimeout() for guaranteed delivery with retries.
See also
writeAll() To send full content regardless of time
writeWithTotalTimeout() To retry until timeout expires
SocketTimeoutException For timeout-specific error classification

◆ writeFrom()

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.

Example Usage

const uint8_t buffer[] = { 0x01, 0x02, 0x03 };
std::size_t sent = sock.writeFrom(buffer, sizeof(buffer));
Parameters
[in]dataPointer to the memory to write.
[in]lenNumber of bytes to send.
Returns
The number of bytes successfully written (can be < len).
Exceptions
SocketExceptionIf:
  • The socket is invalid
  • send() fails due to a network error
  • Connection is closed
Note
This method does not guarantee full delivery. Use writeFromAll() for that.
See also
write() For std::string_view interface
writeFromAll() To guarantee full transmission
readInto() For symmetric read into raw buffer

◆ writeFromAll()

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().

Example Usage

std::vector<uint8_t> payload = generateMessage();
sock.writeFromAll(payload.data(), payload.size());
Parameters
[in]dataPointer to the binary buffer to send.
[in]lenNumber of bytes to transmit.
Returns
The total number of bytes written (equal to len on success).
Exceptions
SocketExceptionIf:
  • The socket is invalid
  • send() fails
  • The connection is closed prematurely
Note
This method blocks until all data is sent or an error occurs. For partial/best-effort sends, use writeFrom() instead.
See also
writeFrom() For best-effort version
writeAll() For string-based equivalent
readIntoExact() For guaranteed binary reads

◆ writePrefixed() [1/2]

template<typename T>
std::size_t jsocketpp::Socket::writePrefixed ( const std::string_view payload)
inline

Writes a length-prefixed payload using a fixed-size integral prefix.

Sends a message that consists of a length prefix followed by the actual payload. The prefix is encoded in network byte order to ensure cross-platform compatibility.

Implementation Details

  • The length of the payload is cast to type T (must not exceed its maximum value)
  • The prefix is converted to network byte order using net::toNetwork()
  • The prefix is copied into a properly aligned buffer to avoid undefined behavior
  • The prefix is written first, followed immediately by the payload
  • This overload accepts any std::string_view, allowing use with string literals, slices, or raw binary buffers

Example Usage

Socket sock("example.com", 8080);
sock.connect();
std::string_view msg = "Hello, world!";
// Send message with 32-bit length prefix
std::size_t totalBytes = sock.writePrefixed<uint32_t>(msg);
std::cout << "Sent " << totalBytes << " bytes\\n";

Protocol Format

+----------------+----------------------+
| Length (T)     | Payload (n bytes)    |
+----------------+----------------------+
|<- sizeof(T) ->|<---- length ------->|
Template Parameters
TThe unsigned integral type used for the length prefix (e.g., uint32_t). Must be trivially copyable.
Parameters
[in]payloadThe payload data to send. The length of this view will be encoded as the prefix and must not exceed the maximum representable value of type T.
Returns
The total number of bytes written (prefix + payload).
Exceptions
SocketExceptionIf:
  • Writing the prefix or payload fails
  • Payload size exceeds the maximum encodable value for type T
  • The connection is closed or interrupted
Note
The prefix is automatically converted to network byte order using jsocketpp::net::toNetwork(). The receiving side must decode it using readPrefixed<T>() or equivalent logic.
See also
readPrefixed() To decode the corresponding message
writeAll() To write data without a length prefix
net::toNetwork() For details on byte order conversion

◆ writePrefixed() [2/2]

template<typename T>
std::size_t jsocketpp::Socket::writePrefixed ( const void * data,
std::size_t len ) const
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.

Implementation Details

  • Validates that len fits within the range of type T
  • Converts the prefix to network byte order using net::toNetwork()
  • Sends sizeof(T) bytes of the length prefix
  • Sends len bytes of raw payload data immediately afterward
  • Uses writeAll() to ensure full delivery of both parts

Example Usage

std::vector<uint8_t> imageData = loadImage();
sock.writePrefixed<uint32_t>(imageData.data(), imageData.size());

Protocol Format

+----------------+----------------------+
| Length (T)     | Payload (n bytes)   |
+----------------+----------------------+
|<- sizeof(T) ->|<---- len --------->|
Template Parameters
TThe unsigned integral type used for the length prefix (e.g., uint32_t). Must be a trivially copyable type.
Parameters
[in]dataPointer to the binary payload data.
[in]lenNumber of bytes to write from data.
Returns
Total number of bytes written (sizeof(T) + len).
Exceptions
SocketExceptionIf:
  • len exceeds the maximum value representable by T
  • If data is null and len > 0
  • Writing the prefix or payload fails
  • Connection is closed or interrupted
Note
The prefix is automatically converted to network byte order using jsocketpp::net::toNetwork(). Receivers must decode it accordingly using readPrefixed<T>() or equivalent.
See also
readPrefixed() For the corresponding deserialization method
writeAll() For guaranteed single-buffer transmission
writePrefixed(std::string) For the string-based variant
net::toNetwork() For details on byte order conversion

◆ writev()

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.

Implementation Details

  • On POSIX: uses writev() with struct iovec[]
  • On Windows: uses WSASend() with WSABUF[]
  • Handles up to IOV_MAX or WSABUF_MAX entries (platform limit)
  • Ensures the total byte count written is returned

Example Usage

std::string_view header = "Content-Length: 12\r\n\r\n";
std::string_view body = "Hello world!";
std::array<std::string_view, 2> segments = {header, body};
std::size_t sent = sock.writev(segments);
Parameters
[in]buffersA span of string views to send as a scatter/gather I/O batch.
Returns
Total number of bytes sent.
Exceptions
SocketExceptionIf:
  • Socket is not connected
  • System I/O call fails
  • Connection is broken or interrupted
Note
This function does not retry partial writes. You must manually check the return value and retry unsent segments if needed.
See also
write() For single-buffer sends
writeAll() To send all bytes in a single string

◆ writevAll()

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().

Implementation Details

  • Uses writev() or WSASend() to send as much as possible
  • Tracks which buffers are partially sent
  • Rebuilds the buffer list on each retry to resume from the last offset
  • Stops only when all buffers are fully transmitted or an error occurs

Example Usage

std::array<std::string_view, 3> fragments = {
"HTTP/1.1 200 OK\r\n",
"Content-Length: 5\r\n\r\n",
"Hello"
};
sock.writevAll(fragments);
Parameters
[in]buffersA span of string fragments to send as a contiguous logical payload.
Returns
Total number of bytes written (equal to sum of all buffer sizes).
Exceptions
SocketExceptionIf:
  • A send error occurs
  • The connection is closed mid-transmission
Note
This method guarantees full delivery, unlike writev(), which may send only part.
See also
writev() For single-shot scatter/gather write
writeAll() For full single-buffer delivery
write() For low-level single-buffer writes

◆ writevFrom()

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.

Example Usage

std::array<std::byte, 4> header = ...;
std::vector<std::byte> body = ...;
std::array<BufferView, 2> buffers = {
BufferView{header.data(), header.size()},
BufferView{body.data(), body.size()}
};
std::size_t sent = sock.writevFrom(buffers);
Parameters
[in]buffersA span of BufferView elements (data + size).
Returns
Number of bytes successfully written (can be < total).
Exceptions
SocketExceptionIf:
  • The socket is invalid
  • sendv fails (e.g., WSA error, broken pipe)
See also
writevFromAll() For full-delivery retry logic
writev() For string-based scatter I/O

◆ writevFromAll()

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().

Example Usage

std::array<std::byte, 8> header;
std::vector<std::byte> body;
std::array<BufferView, 2> buffers = {
BufferView{header.data(), header.size()},
BufferView{body.data(), body.size()}
};
sock.writevFromAll(buffers);
Parameters
[in]buffersA span of raw buffers to send completely.
Returns
Total number of bytes written (equal to sum of buffer sizes).
Exceptions
SocketExceptionIf:
  • A socket error occurs during send
  • The connection is closed prematurely
Note
This method blocks until completion or error. Use writevFrom() for best-effort, single-attempt version.
See also
writevFrom() For non-retrying variant
writevAll() For string-view based equivalent

◆ writevFromWithTotalTimeout()

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 partial writes as needed until all data is delivered or the specified timeout period elapses. If the timeout expires before completing the transmission, a SocketTimeoutException is thrown.

This is the binary-buffer equivalent of writevWithTotalTimeout(), intended for use with low-level, structured protocols or custom serialization layers.

Implementation Details

  • Enforces a wall-clock timeout using std::chrono::steady_clock.
  • Waits for writability using waitReady() before each write attempt.
  • Uses writevFrom() to send multiple non-contiguous memory blocks efficiently.
  • After partial writes, dynamically adjusts buffer offsets to resume transmission.

Example Usage

std::array<std::byte, 4> hdr = ...;
std::vector<std::byte> body = ...;
std::array<BufferView, 2> bufs = {
BufferView{hdr.data(), hdr.size()},
BufferView{body.data(), body.size()}
};
try {
sock.writevFromWithTotalTimeout(bufs, 2000); // must finish in 2s
std::cout << "Transmission complete.\n";
} catch (const SocketTimeoutException& e) {
std::cerr << "Write timed out: " << e.what() << std::endl;
} catch (const SocketException& e) {
std::cerr << "Write error: " << e.what() << std::endl;
}
Parameters
[in]buffersA span of BufferView objects representing raw memory regions to send.
[in]timeoutMillisTotal timeout duration in milliseconds across all write attempts.
Returns
Total number of bytes written (equal to the sum of all buffer sizes on success).
Exceptions
SocketTimeoutExceptionIf:
  • The socket does not become writable within the remaining timeout
  • The full payload is not sent before the deadline expires
SocketExceptionIf:
  • writevFrom() fails due to a system or network error
  • The socket is invalid or disconnected
  • The connection is closed during transmission
Note
This is the low-level, binary-buffer counterpart to writevWithTotalTimeout(). Use writevFromAll() for unbounded full delivery.
See also
writevFromAll() For retrying without a timeout
writevWithTotalTimeout() For std::string_view-based variant
SocketTimeoutException For timeout-specific error handling

◆ writevWithTotalTimeout()

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 provided span using scatter/gather I/O. Retries partial sends as needed, resuming from where the last send left off. The entire operation must complete within timeoutMillis milliseconds or a SocketTimeoutException will be thrown.

This method guarantees that all data across all buffers will be sent in order—or none at all. It is the timeout-aware variant of writevAll() and suitable for time-bounded, multi-buffer transmission (e.g., structured headers + body).

Implementation Details

  • Uses std::chrono::steady_clock to enforce a total wall-clock timeout.
  • Waits for writability using waitReady(true, remainingTime) between sends.
  • Uses writev() to send multiple buffers in one system call.
  • After partial sends, dynamically rebuilds the buffer span to reflect unsent data.

Example Usage

std::array<std::string_view, 3> parts = {
"Header: ",
"value\r\n\r\n",
"Body content"
};
try {
sock.writevWithTotalTimeout(parts, 1500); // Must finish in 1.5 seconds
std::cout << "Message sent.\n";
} catch (const SocketTimeoutException& e) {
std::cerr << "Write timeout: " << e.what() << std::endl;
} catch (const SocketException& e) {
std::cerr << "Write failure: " << e.what() << std::endl;
}
Parameters
[in]buffersSpan of string views representing logically distinct memory segments to send in order.
[in]timeoutMillisTotal allowed duration in milliseconds to complete the operation.
Returns
Total number of bytes sent (must equal the sum of all buffer sizes on success).
Exceptions
SocketTimeoutExceptionIf:
  • The socket does not become writable in time
  • The full payload is not sent before the timeout expires
SocketExceptionIf:
  • writev() fails due to a system or network error
  • The socket is closed or invalid
  • The connection is interrupted during transmission
Note
This method guarantees complete delivery of all buffers, bounded by time. Use writevAll() for unbounded retries or writev() for a single attempt.
See also
writevAll() For unlimited retries and guaranteed delivery
writeWithTotalTimeout() For single-buffer full delivery under timeout
SocketTimeoutException To differentiate timeout from generic network errors

◆ writeWithTotalTimeout()

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 send the entire contents of data, retrying partial writes as needed. The complete operation must finish within timeoutMillis milliseconds or it will throw a SocketTimeoutException.

This method ensures full delivery like writeAll(), but it is time-bounded by wall-clock time. It is suitable for real-time or responsiveness-sensitive applications where you must send everything or fail within a deadline.

Implementation Details

  • Uses std::chrono::steady_clock to enforce a wall-clock deadline.
  • Calls waitReady(true, remainingTime) before each send() attempt.
  • Retries partial writes until complete or until timeout is reached.
  • Returns the total number of bytes sent (equal to data.size() on success).

Example Usage

std::string json = buildPayload();
try {
sock.writeWithTotalTimeout(json, 1000); // Must finish in 1 second
std::cout << "Payload sent.\n";
} catch (const SocketTimeoutException& e) {
std::cerr << "Timed out: " << e.what() << std::endl;
} catch (const SocketException& e) {
std::cerr << "Write error: " << e.what() << std::endl;
}
Parameters
[in]dataThe data to send.
[in]timeoutMillisMaximum time in milliseconds to send the full payload.
Returns
Total number of bytes written (equals data.size() on success).
Exceptions
SocketTimeoutExceptionIf:
  • The socket does not become writable in time
  • The full payload could not be sent before the deadline
SocketExceptionIf:
  • send() fails due to a network or system error
  • The socket is closed or invalid
  • The connection is closed during the operation
Note
This method guarantees full delivery or throws. Use writeAll() for unbounded retries.
See also
writeAll() For guaranteed delivery without time constraint
writeAtMostWithTimeout() For single-shot, best-effort delivery
SocketTimeoutException To catch time-limit-specific failures

◆ ~ServerSocket()

ServerSocket::~ServerSocket ( )
overridenoexcept

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:

  • Closes the underlying socket handle/descriptor if still open
  • Frees any allocated memory for address structures
  • Releases system socket resources
  • Sets internal state to closed/invalid

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.

Resource Cleanup

  • Socket handle is closed via close()
  • Address info structures (_srvAddrInfo) are freed
  • Internal buffers and state are reset

Thread Safety

  • This destructor is not thread-safe
  • The ServerSocket must not be used by other threads during destruction
  • If multiple threads might access the socket during shutdown, external synchronization is required
Warning
  • Do not destroy a ServerSocket while other threads are using it
  • Ensure all client operations are complete before destruction
  • Use proper synchronization if the socket might be accessed during shutdown
See also
close()
Socket

◆ ~Socket()

Socket::~Socket ( )
overridenoexcept

Destructs the Socket object, closing connections and freeing resources.

This destructor ensures proper cleanup of all resources owned by the Socket:

  • Closes the socket file descriptor if still open
  • Frees any allocated address information structures
  • Releases internal buffers

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.

Note
This destructor is thread-safe with respect to other Socket instances but not with concurrent operations on the same Socket object.
See also
close() For explicit connection closure before destruction
shutdown() For controlled shutdown of specific socket operations

Friends

◆ ServerSocket

friend class ServerSocket
friend

Grants ServerSocket access to private members.

ServerSocket needs access to Socket's private members during accept() operations to:

  • Initialize client Socket objects directly with the accepted socket descriptor
  • Set address information for the connected client
  • Configure internal buffers
See also
ServerSocket::accept() Creates new Socket instances from accepted connections
Socket(SOCKET,const sockaddr_storage&,socklen_t,std::size_t,std::size_t,std::size_t) Protected constructor used by accept()