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 (Port port, std::string_view localAddress={}, bool autoBindListen=true, bool reuseAddress=true, int soTimeoutMillis=-1, bool dualStack=true)
 Constructs a ServerSocket for listening to incoming TCP connections with full configuration control.
std::string jsocketpp::ServerSocket::getInetAddress () const
 Get the local IP address to which the server socket is bound.
Port jsocketpp::ServerSocket::getLocalPort () const
 Retrieve the local port number to which the server socket is bound.
std::string jsocketpp::ServerSocket::getLocalSocketAddress () const
 Get the local socket address (IP and port) to which the server socket is bound.
 jsocketpp::ServerSocket::ServerSocket (const ServerSocket &rhs)=delete
 Copy constructor (deleted).
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
 Destructor that automatically closes the server socket and releases all associated resources.
void jsocketpp::ServerSocket::bind ()
 Binds the server socket to the configured port and network interface.
bool jsocketpp::ServerSocket::isBound () const noexcept
 Check if the server socket is bound to a local address.
void jsocketpp::ServerSocket::listen (int backlog=128)
 Marks the socket as a passive (listening) socket, ready to accept incoming TCP connection requests.
bool jsocketpp::ServerSocket::isListening () const noexcept
 Check if the server socket is currently listening for incoming connections.
Socket jsocketpp::ServerSocket::accept (std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) const
 Accept an incoming client connection, respecting the configured socket timeout.
Socket jsocketpp::ServerSocket::accept (int timeoutMillis, std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) const
 Accept an incoming client connection, waiting up to the specified timeout.
std::optional< 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) const
 Attempt to accept an incoming client connection, returning immediately or after the configured timeout.
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) const
 Attempt to accept an incoming client connection, waiting up to a specified timeout.
Socket jsocketpp::ServerSocket::acceptBlocking (std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) const
 Accept an incoming client connection, always blocking until a client connects (unless the socket is set to non-blocking).
std::optional< 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) const
 Attempt to accept a client connection in non-blocking fashion.
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) const
 Asynchronously accept an incoming client connection, returning a future.
void jsocketpp::ServerSocket::acceptAsync (std::function< void(std::optional< Socket >, std::exception_ptr)> callback, std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt) const
 Asynchronously accept a client connection and invoke a callback upon completion.
void jsocketpp::ServerSocket::close ()
 Closes the server socket and releases its associated system resources.
bool jsocketpp::ServerSocket::isValid () const noexcept
 Check whether the server socket is currently open and valid.
bool jsocketpp::ServerSocket::isClosed () const noexcept
 Check if the server socket has been closed.
void jsocketpp::ServerSocket::setOption (int level, int optName, int value)
 Set a socket option for the listening server socket.
int jsocketpp::ServerSocket::getOption (int level, int optName) const
 Retrieve the current value of a socket option for the listening server socket.
static int jsocketpp::ServerSocket::getSocketReuseOption ()
 Returns the correct socket option constant for address reuse, depending on the platform.
void jsocketpp::ServerSocket::setReuseAddress (bool enable)
 Enable or disable address reuse for this server socket.
bool jsocketpp::ServerSocket::getReuseAddress () const
 Query whether the address reuse option is enabled on this server socket.
void jsocketpp::ServerSocket::setNonBlocking (bool nonBlocking)
 Set the server socket to non-blocking or blocking mode.
bool jsocketpp::ServerSocket::getNonBlocking () const
 Check if the server socket is in non-blocking mode.
bool jsocketpp::ServerSocket::waitReady (std::optional< int > timeoutMillis=std::nullopt) const
 Wait for the server socket to become ready to accept an incoming connection.
void jsocketpp::ServerSocket::setSoTimeout (const int timeoutMillis)
 Set the logical timeout (in milliseconds) for accepting client connections.
int jsocketpp::ServerSocket::getSoTimeout () const noexcept
 Get the logical timeout (in milliseconds) for accept operations.
void jsocketpp::ServerSocket::setIPv6Only (bool enable)
 Enable or disable IPv6-only mode for this server socket.
bool jsocketpp::ServerSocket::getIPv6Only () const
 Query whether IPv6-only mode is enabled.
void jsocketpp::ServerSocket::setDefaultReceiveBufferSize (const std::size_t size)
 Set the default receive buffer size for accepted client sockets.
std::size_t jsocketpp::ServerSocket::getDefaultReceiveBufferSize () const noexcept
 Get the current default receive buffer size for accepted client sockets.
void jsocketpp::ServerSocket::setDefaultSendBufferSize (const std::size_t size)
 Set the default send buffer size for accepted client sockets.
std::size_t jsocketpp::ServerSocket::getDefaultSendBufferSize () const noexcept
 Get the current default send buffer size for accepted client sockets.
void jsocketpp::ServerSocket::setDefaultInternalBufferSize (const std::size_t size)
 Set the per-instance default internal buffer size used for buffered read operations.
std::size_t jsocketpp::ServerSocket::getDefaultInternalBufferSize () const noexcept
 Get the per-instance default internal buffer size used for buffered read operations.
void jsocketpp::ServerSocket::setReusePort (bool enable)
 Enable or disable the SO_REUSEPORT socket option.
bool jsocketpp::ServerSocket::getReusePort () const
 Query whether SO_REUSEPORT is enabled for this socket.
SOCKET jsocketpp::ServerSocket::getHandle () const
 Get the underlying native socket handle/descriptor.
void jsocketpp::ServerSocket::cleanupAndThrow (int errorCode)
 Cleans up server socket resources and throws a SocketException.
std::size_t jsocketpp::ServerSocket::getEffectiveReceiveBufferSize (const std::optional< std::size_t > recvBufferSize) const
 Get the effective receive buffer size to use for socket read operations.
std::size_t jsocketpp::ServerSocket::getEffectiveSendBufferSize (std::optional< std::size_t > sendBufferSize) const
 Get the effective send buffer size to use for socket write operations.
std::size_t jsocketpp::ServerSocket::getEffectiveInternalBufferSize (std::optional< std::size_t > internalBufferSize) const
 Get the effective internal buffer size to use for buffered socket read operations.
std::tuple< std::size_t, std::size_t, std::size_t > jsocketpp::ServerSocket::resolveBuffers (const std::optional< std::size_t > recv, const std::optional< std::size_t > send, const std::optional< std::size_t > internal) const
 Resolves effective receive and send buffer sizes from optional user inputs.
 jsocketpp::Socket::Socket (SOCKET client, const sockaddr_storage &addr, socklen_t len, std::size_t recvBufferSize, std::size_t sendBufferSize, std::size_t internalBufferSize)
 Protected constructor used internally to create Socket objects for accepted client connections.
 jsocketpp::Socket::Socket ()=delete
 Default constructor (deleted) for Socket class.
 jsocketpp::Socket::Socket (std::string_view host, Port port, std::optional< std::size_t > recvBufferSize=std::nullopt, std::optional< std::size_t > sendBufferSize=std::nullopt, std::optional< std::size_t > internalBufferSize=std::nullopt)
 Creates a new Socket object configured to connect to the specified host and port.
 jsocketpp::Socket::Socket (const Socket &rhs)=delete
 Copy constructor (deleted) for Socket class.
 jsocketpp::Socket::Socket (Socket &&rhs) noexcept
 Move constructor that transfers ownership of socket resources.
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
 Destructs the Socket object, closing connections and freeing resources.
std::string jsocketpp::Socket::getRemoteSocketAddress (bool convertIPv4Mapped=true) const
 Get the remote peer's address and port as a formatted string.
void jsocketpp::Socket::connect (int timeoutMillis=-1) const
 Establishes a TCP connection to the remote host with optional timeout control.
template<typename T>
jsocketpp::Socket::read ()
 Reads a fixed-size trivially copyable value of type T from the socket.
std::string jsocketpp::Socket::readExact (std::size_t n) const
 Read exactly n bytes from the socket into a string.
std::string jsocketpp::Socket::readUntil (char delimiter, std::size_t maxLen=8192, bool includeDelimiter=true) const
 Reads data from the socket until a specified delimiter character.
std::string jsocketpp::Socket::readLine (const std::size_t maxLen=8192, const bool includeDelimiter=true) const
 Reads a line terminated by '
' from the socket.
std::string jsocketpp::Socket::readAtMost (std::size_t n) const
 Reads up to n bytes from the socket into a string.
std::size_t jsocketpp::Socket::readInto (void *buffer, const std::size_t len) const
 Reads available data from the socket into the provided buffer.
std::size_t jsocketpp::Socket::readIntoExact (void *buffer, const std::size_t len) const
 Reads exactly len bytes into the given buffer (looped recv).
std::string jsocketpp::Socket::readAtMostWithTimeout (std::size_t n, int timeoutMillis) const
 Performs a best-effort read up to n bytes, with a maximum timeout.
template<typename T>
std::string jsocketpp::Socket::readPrefixed ()
 Reads a length-prefixed payload using a fixed-size prefix type.
template<typename T>
std::string jsocketpp::Socket::readPrefixed (const std::size_t maxPayloadLen)
 Reads a length-prefixed message with an upper bound check.
std::string jsocketpp::Socket::readAvailable () const
 Reads all bytes currently available on the socket without blocking.
std::size_t jsocketpp::Socket::readIntoAvailable (void *buffer, std::size_t bufferSize) const
 Reads all currently available bytes into the provided buffer without blocking.
std::size_t jsocketpp::Socket::readv (std::span< BufferView > buffers) const
 Performs a vectorized read into multiple buffers using a single system call.
std::size_t jsocketpp::Socket::readvAll (std::span< BufferView > buffers) const
 Reads exactly the full contents of all provided buffers.
std::size_t jsocketpp::Socket::readvAllWithTotalTimeout (std::span< BufferView > buffers, int timeoutMillis) const
 Reads exactly the full contents of all buffers within a timeout.
std::size_t jsocketpp::Socket::readvAtMostWithTimeout (std::span< BufferView > buffers, int timeoutMillis) const
 Attempts a single vectorized read into multiple buffers with a timeout.
std::string jsocketpp::Socket::peek (std::size_t n) const
 Peeks at incoming data without consuming it.
void jsocketpp::Socket::discard (std::size_t n, std::size_t chunkSize=1024) const
 Discards exactly n bytes from the socket by reading and discarding them.
void jsocketpp::Socket::close ()
 Closes the socket connection and releases associated resources.
void jsocketpp::Socket::shutdown (ShutdownMode how) const
 Shutdown specific communication aspects of the socket.
size_t jsocketpp::Socket::write (std::string_view message) const
 Writes data to the socket, handling partial writes.
size_t jsocketpp::Socket::writeAll (std::string_view message) const
 Writes the entire contents of a message to the socket, handling partial writes.
template<typename T>
std::size_t jsocketpp::Socket::writePrefixed (const std::string &payload)
 Writes a length-prefixed payload using a fixed-size prefix type.
template<typename T>
std::size_t jsocketpp::Socket::writePrefixed (const void *data, std::size_t len) const
 Writes a binary payload prefixed with its length using a fixed-size integer type.
std::size_t jsocketpp::Socket::writev (std::span< const std::string_view > buffers) const
 Writes multiple buffers in a single system call using scatter/gather I/O.
std::size_t jsocketpp::Socket::writevAll (std::span< const std::string_view > buffers) const
 Writes all buffers fully using vectorized I/O with automatic retry on partial sends.
std::size_t jsocketpp::Socket::writeAtMostWithTimeout (std::string_view data, int timeoutMillis) const
 Performs a best-effort write with a total timeout.
std::size_t jsocketpp::Socket::writeFrom (const void *data, std::size_t len) const
 Writes up to len bytes from a raw memory buffer in a single send call.
std::size_t jsocketpp::Socket::writeFromAll (const void *data, std::size_t len) const
 Writes all bytes from a raw memory buffer, retrying until complete.
std::size_t jsocketpp::Socket::writeWithTotalTimeout (std::string_view data, int timeoutMillis) const
 Writes the full payload with a total timeout across all retries.
std::size_t jsocketpp::Socket::writevWithTotalTimeout (std::span< const std::string_view > buffers, int timeoutMillis) const
 Writes all buffers fully within a total timeout using vectorized I/O.
std::size_t jsocketpp::Socket::writevFrom (std::span< const BufferView > buffers) const
 Writes multiple raw memory regions using vectorized I/O.
std::size_t jsocketpp::Socket::writevFromAll (std::span< BufferView > buffers) const
 Writes all raw memory regions fully using scatter/gather I/O.
std::size_t jsocketpp::Socket::writevFromWithTotalTimeout (std::span< BufferView > buffers, int timeoutMillis) const
 Writes all raw memory buffers fully within a timeout using scatter I/O.
void jsocketpp::Socket::setReceiveBufferSize (std::size_t size)
 Sets the socket's receive buffer size (SO_RCVBUF).
void jsocketpp::Socket::setSendBufferSize (std::size_t size)
 Sets the socket's send buffer size (SO_SNDBUF).
int jsocketpp::Socket::getReceiveBufferSize () const
 Get the socket's receive buffer size (SO_RCVBUF).
int jsocketpp::Socket::getSendBufferSize () const
 Get the socket's send buffer size (SO_SNDBUF).
void jsocketpp::Socket::setInternalBufferSize (std::size_t newLen)
 Sets the size of the internal read buffer used for string operations.
bool jsocketpp::Socket::isValid () const noexcept
 Check if the socket is valid and open for communication.
void jsocketpp::Socket::setNonBlocking (bool nonBlocking) const
 Set the socket to non-blocking or blocking mode.
bool jsocketpp::Socket::getNonBlocking () const
 Check if the socket is currently in non-blocking mode.
void jsocketpp::Socket::setSoTimeout (int millis, bool forRead=true, bool forWrite=true)
 Set timeout for socket send and/or receive operations.
std::size_t jsocketpp::Socket::readIntoInternal (void *buffer, std::size_t len, bool exact=false) const
 Reads data from the socket into a user-supplied buffer.
void jsocketpp::Socket::cleanupAndThrow (int errorCode)
 Cleans up client socket resources and throws a SocketException.
template<>
std::string jsocketpp::Socket::read ()
 Template specialization to read a string from the socket.

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 ) const
nodiscard

Accept an incoming client connection, waiting up to the specified timeout.

Note
This method is not thread safe. Simultaneous calls to accept() or acceptNonBlocking() from multiple threads (or processes) may result in race conditions or unexpected exceptions.

Waits for an incoming client connection using the timeout specified by the timeoutMillis parameter:

  • If timeoutMillis is negative, the method blocks indefinitely until a client connects.
  • If timeoutMillis is zero, the method polls and returns immediately if no client is waiting.
  • If timeoutMillis is positive, the method waits up to that many milliseconds for a connection, then throws a SocketTimeoutException if none arrives.

Internally, this method uses waitReady(timeoutMillis) (which uses select()) to wait for readiness, then calls acceptBlocking() with the resolved buffer sizes. If the timeout expires with no client, a SocketTimeoutException is thrown.

The blocking or non-blocking mode of the server socket (via setNonBlocking()) does not affect the waiting behavior of this method, since select() is used for readiness detection.

Note
Use this method to specify a timeout per call. To configure a default for all accepts, use setSoTimeout(). For non-blocking polling, use tryAccept() or acceptNonBlocking().
Parameters
[in]timeoutMillisTimeout in milliseconds to wait for a client connection:
  • Negative: block indefinitely
  • Zero: poll once
  • Positive: wait up to this many milliseconds
[in]recvBufferSizeThe receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize().
[in]sendBufferSizeThe send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize().
[in]internalBufferSizeThe internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize().
Returns
A Socket object representing the connected client.
Exceptions
SocketExceptionif the server socket is invalid or closed, or if an internal error occurs.
SocketTimeoutExceptionif no client connects before the timeout expires.
Precondition
Server socket must be valid, bound, and listening.
Postcondition
A new connected Socket is returned on success.
See also
accept()
tryAccept()
acceptBlocking()
setSoTimeout()
waitReady()
server.bind();
server.listen();
try {
jsocketpp::Socket client = server.accept(2000); // Wait up to 2 seconds
// Handle client...
std::cout << "No client connected within timeout." << std::endl;
}
TCP server socket abstraction for cross-platform C++ networking.
Definition ServerSocket.hpp:100
Exception class for socket operations that time out.
Definition SocketTimeoutException.hpp:39
TCP client connection abstraction (Java-like interface).
Definition Socket.hpp:91

◆ 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 ) const
nodiscard

Accept an incoming client connection, respecting the configured socket timeout.

Note
This method is not thread safe. Simultaneous calls to accept() or acceptNonBlocking() from multiple threads (or processes) may result in race conditions or unexpected exceptions.

Waits for an incoming client connection using the timeout value configured by setSoTimeout().

  • If the timeout is negative (default), the method blocks indefinitely until a client connects.
  • If the timeout is zero, the method polls and returns immediately if no client is waiting.
  • If the timeout is positive, the method waits up to that many milliseconds for a connection, then throws a SocketTimeoutException if none arrives.

Internally, this method uses waitReady() (which internally uses select()) to wait for readiness and only then calls accept(). If the timeout expires with no client, a SocketTimeoutException is thrown.

The blocking or non-blocking mode of the server socket (via setNonBlocking()) does not affect the waiting behavior of this method, since select() is used for waiting.

Note
- Use setSoTimeout() and getSoTimeout() to configure the timeout. For manual non-blocking accept in an event loop, see acceptNonBlocking() and waitReady().
- To safely use accept() in a multithreaded environment, protect access to the ServerSocket with a mutex.
Parameters
[in]recvBufferSizeThe receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize().
[in]sendBufferSizeThe send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize().
[in]internalBufferSizeThe internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize().
Returns
A Socket object representing the connected client.
Exceptions
SocketExceptionif the server socket is not initialized, closed, or if an internal error occurs.
SocketTimeoutExceptionif the timeout expires before a client connects.
Precondition
Server socket must be valid, bound, and listening.
Postcondition
A new connected Socket is returned on success.
See also
setSoTimeout(int)
getSoTimeout()
acceptBlocking()
acceptNonBlocking()
waitReady()

◆ 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 ) const

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

Launches a background thread to perform an accept() operation and calls the user-provided callback when a client connects or an error occurs. This is useful for event-driven servers that require non-blocking, callback-based acceptance of new clients.

The callback is invoked exactly once with:

  • a valid Socket and nullptr exception on success, or
  • an empty std::optional<Socket> and a non-null std::exception_ptr on error.

Internally, this uses a detached std::thread that invokes accept(...), wrapped in a try-catch block. If the server socket is not valid or an error occurs (including timeouts), the exception is captured and passed to the callback for inspection or rethrowing via std::rethrow_exception().

Note
This method is not thread safe. Avoid concurrent calls to accept, acceptAsync, or related methods from multiple threads unless externally synchronized.
The ServerSocket object must remain alive until the callback is invoked. Destroying the object before the background thread finishes is undefined behavior.
Parameters
[in]callbackCompletion handler with signature: void callback(std::optional<Socket>, std::exception_ptr)
[in]recvBufferSizeThe receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize().
[in]sendBufferSizeThe send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize().
[in]internalBufferSizeThe internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize().
Precondition
Server socket must be valid, bound, and listening.
Postcondition
Callback is invoked exactly once with either a valid Socket or an exception.
See also
accept()
tryAccept()
acceptAsync(std::future)
std::optional
std::exception_ptr, std::rethrow_exception
server.acceptAsync(
[](std::optional<jsocketpp::Socket> clientOpt, std::exception_ptr eptr) {
if (eptr) {
try { std::rethrow_exception(eptr); }
catch (const jsocketpp::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, // receive buffer size
4096 // send buffer size
);
Represents socket-related errors in the jsocketpp library.
Definition SocketException.hpp:58

◆ 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 ) const
nodiscard

Asynchronously accept an incoming client connection, returning a future.

This method launches an asynchronous accept operation on the server socket, returning a std::future<Socket> that resolves once a client connects or an error occurs.

Internally, this uses std::async(std::launch::async, ...) to spawn a background thread that calls accept(...). The calling thread is never blocked.

When a client is accepted, the future becomes ready and yields a fully constructed Socket object. If an error or timeout occurs, the exception is rethrown when .get() is called on the future.

Note
This is not thread safe: do not call acceptAsync(), accept(), or related methods concurrently on the same ServerSocket instance unless externally synchronized.
The ServerSocket object must outlive the returned future. Use caution when capturing this.
Parameters
[in]recvBufferSizeThe receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize().
[in]sendBufferSizeThe send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize().
[in]internalBufferSizeThe internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize().
Returns
A std::future<Socket> that resolves to a connected client socket or throws on error.
Exceptions
SocketExceptionif a fatal socket error occurs.
SocketTimeoutExceptionif a timeout is configured and no client connects.
Precondition
Server socket must be valid, bound, and listening.
Postcondition
Future resolves to a connected Socket, or throws from .get().
See also
accept()
tryAccept()
acceptBlocking()
std::future, std::async
auto future = server.acceptAsync();
// Do other work while waiting...
if (future.wait_for(std::chrono::seconds(5)) == std::future_status::ready) {
jsocketpp::Socket client = future.get();
// Handle client...
} else {
// Timeout or still waiting
}

◆ 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 ) const
nodiscard

Accept an incoming client connection, always blocking until a client connects (unless the socket is set to non-blocking).

This method directly invokes the underlying system accept() on the listening socket.

  • If the socket is in blocking mode (default), this method blocks until a client connects. It ignores any timeout set by setSoTimeout().
  • If the socket is in non-blocking mode, the call returns immediately:
    • If a client is pending, returns a connected Socket.
    • If no client is waiting, throws SocketException with EWOULDBLOCK or EAGAIN.
Comparison with acceptNonBlocking()
  • Both methods behave the same, based on the socket's blocking mode.
  • acceptBlocking() throws on all failures, and is idiomatic for classic server loops.
  • acceptNonBlocking() is used in polling/event-driven code where you want to return std::nullopt when no client is available.
Note
This method does not perform any timeout polling. Use accept() or tryAccept() if you need timeouts.
This method is not thread safe. Simultaneous accept calls on the same socket from multiple threads or processes may result in race conditions or failures.
Parameters
[in]recvBufferSizeThe receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize().
[in]sendBufferSizeThe send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize().
[in]internalBufferSizeThe internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize().
Returns
A Socket object representing the connected client.
Exceptions
SocketExceptionif the server socket is invalid or accept() fails (including with EWOULDBLOCK or EAGAIN in non-blocking mode).
Precondition
Server socket must be valid, bound, and listening.
Postcondition
A new connected Socket is returned on success.
See also
accept()
tryAccept()
acceptNonBlocking()
setNonBlocking()
waitReady()
server.bind();
server.listen();
// Blocking example
jsocketpp::Socket client = server.acceptBlocking();
// Non-blocking pattern
server.setNonBlocking(true);
try {
jsocketpp::Socket client = server.acceptBlocking();
// Handle client
} catch (const jsocketpp::SocketException& e) {
if (e.code() == EWOULDBLOCK) {
// No client yet
} else {
throw;
}
}
void setNonBlocking(bool nonBlocking) const
Set the socket to non-blocking or blocking mode.
Definition Socket.cpp:342

◆ 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 ) const
nodiscard

Attempt to accept a client connection in non-blocking fashion.

This method attempts to accept an incoming client connection using the system accept() call:

  • If the server socket is in blocking mode (default), the call will block until a client connects.
  • If the socket is in non-blocking mode (setNonBlocking(true)), the call will return immediately:
    • If a client is ready, returns a Socket object.
    • If no client is waiting, returns std::nullopt.

This method does not use select(), poll(), or any timeout logic. It is ideal for event loops and polling-based architectures where you explicitly check for readiness before accepting.

Note
The blocking behavior depends entirely on the socket mode, which is controlled by setNonBlocking(bool).
For timeout-aware or readiness-checked accept patterns, use accept(), tryAccept(), or acceptBlocking().
Parameters
[in]recvBufferSizeThe receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize().
[in]sendBufferSizeThe send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize().
[in]internalBufferSizeThe internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize().
Returns
A Socket object if a client is connected, or std::nullopt if no connection was ready.
Exceptions
SocketExceptionif the socket is invalid or accept() fails due to a system error (excluding EWOULDBLOCK / EAGAIN on non-blocking sockets).
Precondition
Server socket must be valid, bound, and listening.
Postcondition
Returns a connected Socket or std::nullopt if no client is pending.
See also
accept()
tryAccept()
acceptBlocking()
setNonBlocking()
waitReady()
server.bind();
server.listen();
server.setNonBlocking(true);
while (true) {
auto client = server.acceptNonBlocking();
if (client) {
// Handle client...
} else {
// No client yet; do other work
}
}

◆ bind()

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

◆ cleanupAndThrow() [1/2]

void ServerSocket::cleanupAndThrow ( int errorCode)
protected

Cleans up server socket resources and throws a SocketException.

This method performs cleanup of the address information structures (_srvAddrInfo)

and throws a SocketException with the provided error code. It's typically called when an error occurs during socket initialization or configuration.

Parameters
[in]errorCodeThe error code to include in the thrown exception
Exceptions
SocketExceptionAlways throws with the provided error code and corresponding message

◆ cleanupAndThrow() [2/2]

void Socket::cleanupAndThrow ( int errorCode)
protected

Cleans up client socket resources and throws a SocketException.

This method performs internal cleanup of the client socket's resources, including:

  • Closing the socket if it is open (_sockFd)
  • Releasing any allocated address resolution data (_cliAddrInfo)
  • Resetting _selectedAddrInfo to null

It is used to centralize error recovery during construction or connection setup, ensuring that all partially initialized resources are properly released before rethrowing an exception.

Parameters
[in]errorCodeThe error code to report in the thrown exception.
Exceptions
SocketExceptionAlways throws, containing the error code and the corresponding human-readable error message obtained via SocketErrorMessage(errorCode).
Note
This function is typically called when socket creation, address resolution, or connection setup fails during client socket initialization.

◆ 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, std::size_t sendBufferSize, std::size_t internalBufferSize)
Protected constructor used internally to create Socket objects for accepted client connections.
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) const

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

Attempts to establish a TCP connection to the remote host specified during Socket construction. The connection can be attempted in either blocking or non-blocking mode, depending on the timeout parameter.

Connection Modes

  • Blocking Mode (timeoutMillis < 0):
    • Blocks until connection is established or fails
    • Traditional synchronous behavior
    • Suitable for simple clients
  • Non-blocking Mode with Timeout (timeoutMillis >= 0):
    • Uses select() to monitor connection progress
    • Returns or throws exception after timeout
    • Prevents indefinite blocking
    • Ideal for responsive applications

Example Usage

Socket sock("example.com", 80);
// Blocking connect (will wait indefinitely)
sock.connect();
// Connect with 5-second timeout
try {
sock.connect(5000);
} catch (const SocketException& ex) {
if (ex.getErrorCode() == ETIMEDOUT) {
std::cerr << "Connection timed out\n";
}
}
int getErrorCode() const noexcept
Definition SocketException.hpp:65

Implementation Details

  1. In non-blocking mode:
    • Sets socket to non-blocking
    • Initiates connection (returns EINPROGRESS/WSAEINPROGRESS)
    • Uses select() to wait for completion
    • Verifies connection success
    • Restores blocking mode if needed
  2. In blocking mode:
    • Performs traditional blocking connect()
    • Returns when connected or throws on error
Parameters
[in]timeoutMillisConnection timeout in milliseconds:
  • Negative: blocking mode (no timeout)
  • Zero or positive: maximum wait time
Exceptions
SocketExceptionIn cases of:
  • Connection timeout
  • Connection refused
  • Network unreachable
  • Invalid address
  • Permission denied
  • Other system-specific errors
Note
This method is not thread-safe. Do not call connect() on the same Socket instance from multiple threads simultaneously.
See also
isConnected() Check if connection is established
close() Close the connection
setNonBlocking() Change blocking mode
waitReady() Low-level connection monitoring

◆ 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. This chunk size is chosen as a balance between memory usage and I/O efficiency, but can be tuned for performance.

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(), or the connection is closed before all n bytes are discarded.
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 ( 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
setReceiveBufferSize()
getReceiveBufferSize()
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

◆ getHandle()

SOCKET jsocketpp::ServerSocket::getHandle ( ) const
inlinenodiscard

Get the underlying native socket handle/descriptor.

This method provides low-level access to the native socket handle (file descriptor on Unix-like systems, SOCKET handle on Windows) for advanced usage scenarios such as:

  • Integration with external event loops (select, poll, epoll)
  • Platform-specific socket operations not exposed by the jsocketpp API
  • Custom socket monitoring or diagnostics
Warning
HANDLE WITH CARE:
  • DO NOT close or shutdown the socket using this handle directly
  • DO NOT modify socket options or state without careful consideration
  • DO NOT store the handle beyond the lifetime of the ServerSocket object
  • DO NOT share the handle between threads without proper synchronization

Improper use of the raw socket handle can lead to:

  • Resource leaks
  • Double-close scenarios
  • Undefined behavior
  • Thread safety violations
  • Broken socket state
Note
The handle remains owned and managed by the ServerSocket object. It will be automatically closed when the ServerSocket is destroyed.
Returns
The native socket handle/descriptor
See also
acceptBlocking(), setOption()

◆ getInetAddress()

std::string ServerSocket::getInetAddress ( ) const
nodiscard

Get the local IP address to which the server socket is bound.

Returns the string representation of the IP address (IPv4 or IPv6) the socket is bound to. Useful for debugging, especially when binding to specific interfaces or when binding to "0.0.0.0" or "::" (any address).

Note
This method is thread safe.
Returns
The local IP 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("127.0.0.1", 8080);
server.bind();
std::cout << "Server bound to address: " << server.getInetAddress() << std::endl;
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.
Definition ServerSocket.cpp:8

◆ getIPv6Only()

bool ServerSocket::getIPv6Only ( ) const
nodiscard

Query whether IPv6-only mode is enabled.

Returns
True if the socket is in IPv6-only mode, false if dual-stack.
Exceptions
SocketExceptionif the socket is not IPv6, not open, or on system error.
See also
setIPv6Only()

◆ getLocalPort()

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:315

◆ getLocalSocketAddress()

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;

◆ getNonBlocking() [1/2]

bool ServerSocket::getNonBlocking ( ) const
nodiscard

Check if the server socket is in non-blocking mode.

This function queries the socket's current blocking mode. In non-blocking mode, operations like accept() return immediately if no connection is available, instead of blocking.

Returns
true if the socket is non-blocking, false if it is blocking.
Exceptions
SocketExceptionif the socket flags cannot be retrieved.

◆ getNonBlocking() [2/2]

bool Socket::getNonBlocking ( ) const
nodiscard

Check if the socket is currently in non-blocking mode.

Returns the current blocking mode of the socket. A socket in non-blocking mode will return immediately from operations that would normally block, such as connect(), read(), or write(), with an error code (usually EWOULDBLOCK/WSAEWOULDBLOCK) if the operation cannot be completed immediately.

Implementation Details

  • Uses platform-specific APIs (ioctlsocket on Windows, fcntl on POSIX)
  • Thread-safe with respect to other Socket instances
  • Performs a system call to check current socket state
  • O(1) operation complexity

Example Usage

Socket sock("example.com", 8080);
// Check current blocking mode
bool isNonBlocking = sock.getNonBlocking();
if (!isNonBlocking) {
// Enable non-blocking for async operations
sock.setNonBlocking(true);
}
// Use with waitReady for timeout control
if (sock.getNonBlocking()) {
try {
sock.connect();
} catch (const SocketException& ex) {
if (ex.getErrorCode() == EWOULDBLOCK) {
// Wait up to 5 seconds for connection
if (sock.waitReady(true, 5000)) {
// Connected successfully
}
}
}
}
Returns
true if the socket is in non-blocking mode, false if the socket is in blocking mode (default).
Exceptions
SocketExceptionIf:
  • Socket is invalid (EBADF)
  • System call fails (platform-specific errors)
  • Permission denied (EACCES)
See also
setNonBlocking() Change blocking mode
waitReady() Wait for non-blocking operations
setSoTimeout() Alternative for blocking timeouts

◆ getOption()

int ServerSocket::getOption ( int level,
int optName ) const
nodiscard

Retrieve the current value of a socket option for the listening server socket.

This method lets you query the current setting of a socket option on the listening socket. This is most useful for debugging, for monitoring server configuration, or for verifying a platform's default values.

Note
  • Only options relevant to listening sockets will reflect meaningful values here.
  • To check options for an individual client connection, call getOption on the Socket object returned by accept().

Example: Get the current size of the receive buffer for new connections:

int rcvBuf = serverSocket.getOption(SOL_SOCKET, SO_RCVBUF);
Parameters
[in]levelProtocol level (e.g., SOL_SOCKET)
[in]optNameOption name (e.g., SO_RCVBUF)
Returns
Integer value for the option
Exceptions
SocketExceptionif the operation fails
See also
setOption()

◆ getReceiveBufferSize()

int Socket::getReceiveBufferSize ( ) const
nodiscard

Get the socket's receive buffer size (SO_RCVBUF).

Retrieves the current size of the operating system's receive buffer for this socket. The receive buffer is used by the OS to store incoming data before it is read by the application. A larger buffer can help prevent data loss during high-bandwidth transfers or when the application cannot read data quickly enough.

Implementation Details

  • Uses getsockopt() with SO_RCVBUF option
  • Returns actual buffer size allocated by OS
  • On Linux, returned value may be twice the requested size due to kernel overhead
  • Thread-safe with respect to other Socket instances

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Check current receive buffer size
int size = sock.getReceiveBufferSize();
std::cout << "Current receive buffer: " << size << " bytes\n";
// Increase if needed
if (size < 64 * 1024) {
sock.setReceiveBufferSize(64 * 1024);
size = sock.getReceiveBufferSize();
std::cout << "New receive buffer: " << size << " bytes\n";
}
Returns
Current receive buffer size in bytes. Note that this may differ from the size requested via setReceiveBufferSize() due to OS adjustments and overhead.
Exceptions
SocketExceptionIf:
  • Socket is invalid (EBADF)
  • System call fails (EFAULT)
  • Insufficient permissions
See also
setReceiveBufferSize() For setting the receive buffer size
getSendBufferSize() Get send buffer size
setInternalBufferSize() Set internal string buffer size

◆ getRemoteSocketAddress()

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

Get the remote peer's address and port as a formatted string.

Converts the remote peer's address information (stored in sockaddr_storage) to a human-readable string in the format "address:port". This method supports both IPv4 and IPv6 addresses and optionally handles IPv4-mapped IPv6 addresses.

The conversion process:

  1. Optionally detects and converts IPv4-mapped IPv6 addresses (e.g., "::ffff:192.168.0.1") to plain IPv4 ("192.168.0.1") if convertIPv4Mapped is true.
  2. Uses getnameinfo() to convert the binary address to text.
  3. Formats IPv4 addresses as "x.x.x.x:port".
  4. Formats IPv6 addresses as "[xxxx:xxxx::xxxx]:port".

Example outputs:

  • IPv4: "192.168.1.1:80"
  • IPv6: "[2001:db8::1]:80"
  • IPv4-mapped IPv6:
    • With convertIPv4Mapped = true (default): "192.168.1.1:80"
    • With convertIPv4Mapped = false: "[::ffff:192.168.1.1]:80"
Parameters
[in]convertIPv4MappedWhether to convert IPv4-mapped IPv6 addresses to pure IPv4 form. Default is true.
Returns
A string containing the formatted address and port.
Exceptions
SocketExceptionIf address conversion fails or the socket is invalid.
See also
addressToString() Static utility method for general address conversion.
stringToAddress() Convert string address back to binary form.

◆ getReuseAddress()

bool ServerSocket::getReuseAddress ( ) const
nodiscard

Query whether the address reuse option is enabled on this server socket.

This function checks whether the socket is currently configured to allow reuse of local addresses.

  • On UNIX-like systems, this checks the SO_REUSEADDR socket option.
  • On Windows, this checks SO_EXCLUSIVEADDRUSE, but note that this is semantically opposite: enabling SO_EXCLUSIVEADDRUSE disables address reuse.
Returns
true if address reuse is enabled (i.e., SO_REUSEADDR is set on UNIX-like systems or SO_EXCLUSIVEADDRUSE is unset on Windows); false otherwise.
Exceptions
SocketExceptionif the socket is not valid or the option cannot be retrieved.
Note
This reflects the current state of the reuse flag, which may have been set manually or inherited from system defaults. Always call this after socket creation, and before bind() for accurate results.
See also
setReuseAddress()

◆ getReusePort()

bool ServerSocket::getReusePort ( ) const
nodiscard

Query whether SO_REUSEPORT is enabled for this socket.

This method returns the current status of the SO_REUSEPORT option on this socket. Like setReusePort(), this method is only available on platforms that define SO_REUSEPORT.

Returns
true if SO_REUSEPORT is enabled, false otherwise.
Exceptions
SocketExceptionif querying the option fails.
See also
setReusePort(bool)
https://man7.org/linux/man-pages/man7/socket.7.html

◆ getSendBufferSize()

int Socket::getSendBufferSize ( ) const
nodiscard

Get the socket's send buffer size (SO_SNDBUF).

Retrieves the current size of the operating system's send buffer for this socket. The send buffer is used by the OS to store outgoing data before it is transmitted over the network. A larger buffer can help improve performance during high-bandwidth transfers or when the network is temporarily congested.

Implementation Details

  • Uses getsockopt() with SO_SNDBUF option
  • Returns actual buffer size allocated by OS
  • On Linux, returned value may be twice the requested size due to kernel overhead
  • Thread-safe with respect to other Socket instances

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Check current send buffer size
int size = sock.getSendBufferSize();
std::cout << "Current send buffer: " << size << " bytes\n";
// Increase if needed
if (size < 64 * 1024) {
sock.setSendBufferSize(64 * 1024);
size = sock.getSendBufferSize();
std::cout << "New send buffer: " << size << " bytes\n";
}
Returns
Current send buffer size in bytes. Note that this may differ from the size requested via setSendBufferSize() due to OS adjustments and overhead.
Exceptions
SocketExceptionIf:
  • Socket is invalid (EBADF)
  • System call fails (EFAULT)
  • Insufficient permissions
See also
setSendBufferSize() For setting the send buffer size
getReceiveBufferSize() Get receive buffer size
setInternalBufferSize() Set internal string buffer size

◆ getSocketReuseOption()

int ServerSocket::getSocketReuseOption ( )
staticnodiscard

Returns the correct socket option constant for address reuse, depending on the platform.

  • On Unix/Linux platforms, this returns SO_REUSEADDR, which allows a socket to bind to a local address/port that is in the TIME_WAIT state. This is commonly used for servers that need to restart without waiting for TCP connections to fully time out.
  • On Windows, this returns SO_EXCLUSIVEADDRUSE, which provides safer server semantics: only one socket can bind to a given address/port at a time, but it allows quick server restarts. Using SO_REUSEADDR on Windows has different (and less safe) behavior, potentially allowing multiple sockets to bind to the same port simultaneously, which is almost never what you want for TCP servers.
Returns
The socket option to use with setsockopt() for configuring address reuse in a cross-platform way.
Note
This function should be used to select the correct socket option when calling setsockopt() in your server code. Typically, this option must be set before calling bind().

◆ getSoTimeout()

int jsocketpp::ServerSocket::getSoTimeout ( ) const
inlinenodiscardnoexcept

Get the logical timeout (in milliseconds) for accept operations.

This value determines how long methods like accept() and tryAccept() will wait for an incoming client connection before timing out. It is used internally by select() or similar readiness mechanisms.

Note
This timeout is a logical userland timeout and does not affect the socket descriptor via setsockopt() (unlike Socket::getSoTimeout()).
Returns
The configured accept timeout in milliseconds.
See also
setSoTimeout()
accept()
tryAccept()

◆ isBound()

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.

◆ isClosed()

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

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

◆ 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 (_sockFd) 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
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<typename T>
T jsocketpp::Socket::read ( )
inline

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

Reads exactly sizeof(T) bytes from the socket and interprets them as a complete, binary-safe object of type T. This is useful for reading primitive values and POD (Plain Old Data) structs directly from the stream without any parsing logic.

Implementation Details

  • Allocates a temporary buffer of sizeof(T) bytes
  • Uses recv() in a loop to ensure all bytes are read (handles partial reads)
  • Uses std::memcpy to safely transfer data from buffer to object
  • Performs no endianness conversion or padding adjustment

Usage Example

Socket sock("example.com", 8080);
sock.connect();
try {
int number = sock.read<int>();
double value = sock.read<double>();
struct Header {
uint32_t id;
uint16_t flags;
char tag[16];
};
Header h = sock.read<Header>();
} catch (const SocketException& ex) {
std::cerr << "Read failed: " << ex.what() << std::endl;
}

Supported Types

  • Built-in types (int, float, double, etc.)
  • C-style structs and PODs
  • Arrays or fixed-size containers (e.g., std::array<T, N>)
  • Any type satisfying std::is_trivially_copyable

Thread Safety

  • Not thread-safe: concurrent calls on the same Socket object are unsafe
  • Use one Socket instance per thread or provide external synchronization
Template Parameters
TThe type to read from the socket. Must satisfy std::is_trivially_copyable.
Returns
A fully constructed object of type T populated with bytes read from the stream.
Exceptions
SocketExceptionIf:
  • Connection is closed before read completes
  • Network error occurs (e.g., ECONNRESET, EWOULDBLOCK, ETIMEDOUT)
  • Socket is invalid or not connected (EBADF)
  • Memory allocation fails (e.g., std::bad_alloc)
Warning
Byte Order:
  • No endianness conversion is performed
  • Caller must explicitly decode fields (e.g., using net::fromNetwork())
  • Do not assume identical layout across different platforms
Memory Safety:
  • Avoid types with pointers, virtual functions, custom allocators, or dynamic memory
  • Misuse may result in undefined behavior or security issues
  • Structure padding and alignment may differ between architectures
Note
A temporary buffer is allocated and freed per read; no internal persistent buffer is used.
See also
write() For writing fixed-size types to the socket
readPrefixed() For reading size-prefixed dynamic data
setInternalBufferSize() To adjust internal string buffer size
setSoTimeout() To set socket read timeout
isConnected() To check connection status

◆ read() [2/2]

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

Template specialization to read a string from the socket.

Reads incoming data from the socket into the internal buffer and returns it as a string. This specialization provides string-specific functionality that differs from the generic read<T>() implementation.

Key Features

  • Uses internal buffer for efficient reading
  • Handles partial reads gracefully
  • Supports both text and binary data
  • Returns actual received data length

Implementation Details

  1. Uses internal buffer (_recvBuffer) sized via setInternalBufferSize()
  2. Performs single recv() call up to buffer size
  3. Creates string from received data
  4. Preserves binary data (including null bytes)

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Read with default buffer size (@ref DefaultBufferSize)
std::string data = sock.read<std::string>();
// Read with custom buffer size
sock.setInternalBufferSize(1024);
std::string largeData = sock.read<std::string>();
Returns
std::string containing the received data. Length may be less than buffer size depending on available data.
Exceptions
SocketExceptionIf:
  • Socket error occurs during read
  • Connection is closed by remote host
  • System-specific network errors
Note
This specialization differs from read<T>() in that it doesn't require an exact size match and can handle variable-length data.
See also
setInternalBufferSize() To modify the maximum read length
write() For sending string data
read() Generic version for fixed-size types

◆ readAtMost()

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

Reads up to n bytes from the socket into a string.

Performs a single read operation from the socket, returning immediately with whatever data is available, up to the specified maximum number of bytes. This method provides a "best-effort" read that won't block waiting for more data once some data is available.

Implementation Details

  • Uses a single recv() call
  • Returns immediately when any data is available
  • Does not wait for full buffer
  • Handles partial reads gracefully
  • Thread-safe with respect to other Socket instances

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Read up to 1024 bytes
std::string data = sock.readAtMost(1024);
std::cout << "Received " << data.length() << " bytes\n";
// Use with non-blocking socket
sock.setNonBlocking(true);
try {
std::string partial = sock.readAtMost(512);
// Process whatever data is available
} catch (const SocketException& ex) {
if (ex.getErrorCode() == EWOULDBLOCK) {
// No data currently available
}
}
Parameters
[in]nMaximum number of bytes to read in a single operation. The actual number of bytes read may be less than this value.
Returns
std::string containing between 0 and n bytes of received data. An empty string may indicate that no data was available.
Exceptions
SocketExceptionIf:
  • Socket is invalid (EBADF)
  • Connection is closed by peer (0)
  • Network error occurs (platform-specific)
  • Memory allocation fails (std::bad_alloc)
Note
This method differs from readExact() in that it won't attempt to collect exactly n bytes. It returns as soon as any data is available.
See also
readExact() For reading exact number of bytes
read<std::string>() For reading with internal buffer
setNonBlocking() To control blocking behavior
setSoTimeout() To set read timeout

◆ readAtMostWithTimeout()

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

Performs a best-effort read up to n bytes, with a maximum timeout.

Waits up to timeoutMillis milliseconds for the socket to become readable, then performs a single recv() call for at most n bytes.

Attempts to read up to n bytes from the socket, returning early if:

  • The requested number of bytes are received
  • The timeout period expires
  • The connection is closed by the peer
  • An error occurs

Unlike readExact(), this method returns as soon as any data is available, without waiting for the full requested length. The timeout applies to the initial wait for data availability.

Implementation Details

  • Uses waitReady() to implement timeout
  • Performs single recv() call when data available
  • Returns immediately with available data
  • Does not retry or accumulate partial reads

Example Usage

Socket sock("example.com", 8080);
sock.connect();
try {
// Try to read up to 1024 bytes, waiting max 5 seconds
std::string data = sock.readAtMostWithTimeout(1024, 5000);
std::cout << "Read " << data.length() << " bytes\n";
} catch (const SocketException& ex) {
if (ex.getErrorCode() == ETIMEDOUT) {
// No data available within timeout
}
}
Parameters
[in]nMaximum number of bytes to read
[in]timeoutMillisMaximum time to wait for data, in milliseconds:
  • > 0: Maximum wait time
  • 0: Non-blocking check
  • < 0: Invalid (throws exception)
Returns
String containing between 0 and n bytes of received data
Exceptions
SocketExceptionIf:
  • Socket is invalid
  • Timeout period expires before any data arrives
  • Connection is closed by peer
  • Memory allocation fails
  • Other network errors occur
See also
readExact() For reading exact number of bytes
readAtMost() For immediate best-effort read
waitReady() For lower-level timeout control
setSoTimeout() For setting default timeouts

◆ 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

Read exactly n bytes from the socket into a string.

This method performs a blocking read operation that guarantees to read exactly the requested number of bytes, unless an error occurs. It will continue reading from the socket until all requested bytes are received, handling partial reads transparently.

Implementation Details

  • Uses recv() internally for actual socket operations
  • Handles partial reads by continuing until all data is received
  • Allocates a buffer of exact size needed
  • Maintains original byte order and content

Example Usage

Socket sock("example.com", 8080);
sock.connect();
try {
// Read exactly 1024 bytes
std::string data = sock.readExact(1024);
assert(data.length() == 1024);
} catch (const SocketException& ex) {
// Handle read errors
}
Parameters
[in]nNumber of bytes to read. Must be greater than 0.
Returns
std::string containing exactly n bytes of received data. The returned string's length will always equal n on success.
Exceptions
SocketExceptionIf:
  • Connection is closed by peer (errno = ECONNRESET)
  • Network error occurs (various platform-specific errno values)
  • Read timeout occurs (if configured) (errno = ETIMEDOUT)
  • Memory allocation fails (std::bad_alloc)
  • Socket is invalid or not connected (errno = EBADF)
Note
This method blocks until all requested bytes are received or an error occurs. For non-blocking behavior, use read<std::string>() instead.
See also
read<std::string>() For single-read best-effort operations
read<T>() For reading fixed-size binary types
setSoTimeout() To set read timeout
setNonBlocking() To control 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
bufferPointer to the memory where received data will be stored.
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 ) const
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
maxLenMaximum number of bytes to read (default: 8192)
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
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 ) const

Reads data from the socket until a specified delimiter character.

Reads data from the socket until the specified delimiter character is encountered. The method accumulates data efficiently, handling partial reads and buffer resizing as needed. The returned string optionally includes the delimiter character based on the includeDelimiter parameter.

Implementation Details

  • Uses internal buffer for efficient reading
  • Handles partial reads and buffer resizing
  • Supports arbitrary delimiter characters
  • Enforces maximum length limit
  • Optionally includes delimiter in return value

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Read until newline character
std::string line = sock.readUntil('\n');
// Read with custom delimiter and length limit
std::string csv = sock.readUntil(',', 1024);
// Read without including the delimiter
std::string data = sock.readUntil('\n', 8192, false);
Parameters
[in]delimiterCharacter that marks the end of data
[in]maxLenMaximum allowed data length in bytes (default: 8192)
[in]includeDelimiterWhether to include delimiter in returned string (default: true)
Returns
std::string containing the data up to the delimiter, optionally including the delimiter
Exceptions
SocketExceptionIf:
  • Maximum length is exceeded
  • Connection is closed
  • Read timeout occurs
  • Socket error occurs
  • Memory allocation fails
See also
readLine() For reading newline-terminated data
read() For general-purpose reading
readExact() For fixed-length reads
setSoTimeout() To control read timeout

◆ 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:43
Parameters
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
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 repeatedly performs vectorized reads into the given sequence of buffers until all bytes are read or the timeout expires. It uses a steady clock to track the total time spent across all retries.

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
buffersSpan of BufferView objects describing writable regions.
timeoutMillisMaximum allowed time to read all bytes (in milliseconds).
Returns
Total number of bytes read (equal to sum of buffer sizes on success).
Exceptions
SocketExceptionIf:
  • The timeout expires before all data is read
  • recv() or readv() fails
  • Connection is closed prematurely
Note
This method is fully blocking but timeout-bounded. Use readv() or readvAll() for simpler variants.
See also
readvAll() For unbounded retry version
readv() For best-effort single-attempt vectorized read

◆ 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 for the socket to become readable, then performs a single readv() operation. May read less than the total buffer size. This is the timeout-aware version of readv(), useful for polling or best-effort I/O.

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
Parameters
buffersWritable buffer views to receive incoming data.
timeoutMillisTime to wait for readability before giving up.
Returns
Number of bytes read (can be 0).
Exceptions
SocketExceptionIf:
  • The socket is not readable within timeout
  • recv() or readv() fails
  • Connection is closed
Note
This performs exactly one system read. It does not retry.
See also
readv() For non-timed scatter read
readvAllWithTotalTimeout() For full delivery

◆ 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/3]

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() [2/3]

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() [3/3]

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

◆ setIPv6Only()

void ServerSocket::setIPv6Only ( bool enable)

Enable or disable IPv6-only mode for this server socket.

By default, an IPv6 socket is configured in dual-stack mode (accepts both IPv6 and IPv4 connections) on most platforms. Enabling IPv6-only mode restricts the socket to only IPv6 connections.

Parameters
[in]enableTrue to enable IPv6-only mode, false to allow dual-stack.
Exceptions
SocketExceptionif the socket is not IPv6, already bound, or on system error.
Note
Must be called before bind().
See also
getIPv6Only()

◆ setNonBlocking() [1/2]

void ServerSocket::setNonBlocking ( bool nonBlocking)

Set the server socket to non-blocking or blocking mode.

When in non-blocking mode, the accept() call will return immediately if no connections are pending, instead of blocking until a client connects.

This is useful for integrating the server socket into event loops or custom I/O polling systems.

Note
This only affects the listening server socket. The accepted sockets returned by accept() remain in blocking mode by default and must be configured separately.
Parameters
[in]nonBlockingtrue to enable non-blocking mode, false for blocking (default).
Exceptions
SocketExceptionon error.
See also
acceptBlocking(), acceptNonBlocking()

◆ setNonBlocking() [2/2]

void Socket::setNonBlocking ( bool nonBlocking) const

Set the socket to non-blocking or blocking mode.

Controls whether socket operations (connect, read, write) block until completion or return immediately. In non-blocking mode, operations return immediately with an error (usually EWOULDBLOCK/WSAEWOULDBLOCK) if they cannot be completed, allowing the application to perform other tasks while waiting.

Implementation Details

  • Uses platform-specific APIs (ioctlsocket on Windows, fcntl on POSIX)
  • Affects all subsequent socket operations
  • Thread-safe with respect to other Socket instances
  • State persists until explicitly changed

Example Usage

Socket sock("example.com", 8080);
// Enable non-blocking mode
sock.setNonBlocking(true);
try {
// Will return immediately if can't connect
sock.connect();
} catch (const SocketException& ex) {
if (ex.getErrorCode() == EWOULDBLOCK) {
// Connection in progress
if (sock.waitReady(true, 5000)) {
// Connected within 5 seconds
}
}
}

Common Use Cases

  • Implementing select/poll-based I/O multiplexing
  • Preventing blocking in UI threads
  • Managing multiple connections efficiently
  • Implementing timeouts for operations
Parameters
[in]nonBlockingtrue to enable non-blocking mode, false to enable blocking mode (default).
Exceptions
SocketExceptionIf:
  • Socket is invalid (EBADF)
  • System call fails (platform-specific)
  • Permission denied (EACCES)
See also
getNonBlocking() Check current blocking mode
waitReady() Wait for non-blocking operations
setSoTimeout() Alternative for blocking timeouts

◆ setOption()

void ServerSocket::setOption ( int level,
int optName,
int value )

Set a socket option for the listening server socket.

This method allows you to control low-level parameters of the listening (accepting) server socket. Because this socket is used only to accept new client connections, only certain options are meaningful here. Typical uses include:

  • Allowing the server to quickly re-bind to a port after restart (SO_REUSEADDR)
  • Configuring buffer sizes for incoming connections
  • Tuning low-level TCP behaviors (e.g., SO_KEEPALIVE, SO_RCVBUF, SO_SNDBUF)
Note
  • Changing some options on a listening socket (like SO_LINGER or SO_RCVBUF) only affects the acceptor socket itself, not the individual sockets returned by accept(). For per-client tuning, set options on the accepted Socket objects.
  • Attempting to set unsupported or inappropriate options may result in exceptions or undefined behavior.

Example: Enable port reuse (recommended for most servers):

serverSocket.setOption(SOL_SOCKET, SO_REUSEADDR, 1);
Parameters
[in]levelProtocol level at which the option resides (e.g., SOL_SOCKET, IPPROTO_TCP)
[in]optNameOption name (e.g., SO_REUSEADDR, SO_RCVBUF)
[in]valueInteger value for the option
Exceptions
SocketExceptionif the operation fails
See also
getOption()

◆ setReceiveBufferSize()

void Socket::setReceiveBufferSize ( std::size_t size)

Sets the socket's receive buffer size (SO_RCVBUF).

Configures the size of the operating system's receive buffer for this socket. A larger buffer can improve performance for high-bandwidth connections by allowing the system to buffer more incoming data, reducing the risk of packet loss during temporary processing delays.

Implementation Details

  • Uses setsockopt() with SO_RCVBUF option to set kernel socket buffer size
  • The operating system may adjust the requested size:
    • Linux typically doubles the value to account for bookkeeping overhead
    • Windows may round to system-specific boundaries
    • Maximum size is limited by system settings (/proc/sys/net/core/rmem_max on Linux)
  • Changes affect subsequent receives only, not data already in the buffer
  • System limits may constrain maximum size based on available memory and OS policy

Example Usage

Socket sock("example.com", 80);
// Set 64KB receive buffer
sock.setReceiveBufferSize(64 * 1024);
// Verify actual size (may be different)
int actualSize = sock.getReceiveBufferSize();
std::cout << "Actual receive buffer size: " << actualSize << " bytes\n";
Parameters
[in]sizeDesired receive buffer size in bytes. The actual size allocated may be adjusted by the operating system.
Exceptions
SocketExceptionIf:
  • Socket is invalid
  • System call fails
  • Requested size exceeds system limits
  • Insufficient permissions
Note
Some systems may double the specified size internally. Use getReceiveBufferSize() to verify the actual size.
See also
getSendBufferSize() Get current send buffer size
setInternalBufferSize() Set internal buffer size
setSendBufferSize() Set send buffer size

◆ setReuseAddress()

void ServerSocket::setReuseAddress ( bool enable)

Enable or disable address reuse for this server socket.

When address reuse is enabled (enable = true), the server socket can bind to a local address/port even if a previous socket on that port is still in the TIME_WAIT state. This is useful for restarting servers without waiting for old sockets to time out.

On UNIX-like systems, this sets the SO_REUSEADDR socket option. On Windows, it sets the equivalent option, SO_EXCLUSIVEADDRUSE.

Warning
This method must be called before calling bind(), and only once the socket has been created (i.e., after construction, before bind).
Parameters
[in]enableTrue to enable address reuse, false to disable (default OS behavior).
Exceptions
SocketExceptionif setting the option fails (e.g., socket not open or system error).
Note
Improper use of address reuse can have security and protocol implications. For most server applications, enabling this is recommended. For advanced load-balancing, see also SO_REUSEPORT (not portable).
See also
https://man7.org/linux/man-pages/man7/socket.7.html

◆ setReusePort()

void ServerSocket::setReusePort ( bool enable)

Enable or disable the SO_REUSEPORT socket option.

The SO_REUSEPORT option allows multiple sockets on the same host to bind to the same port number, enabling load balancing of incoming connections across multiple processes or threads. This can dramatically improve scalability for high-performance servers (such as web servers or proxies).

Warning
SO_REUSEPORT is not supported on all platforms. It is available on:
  • Linux kernel 3.9 and later
  • Many BSD systems (FreeBSD 10+, OpenBSD, macOS 10.9+)
  • Not supported on Windows

If you compile or run on a platform where SO_REUSEPORT is unavailable, this method will not be present. Use conditional compilation (#ifdef SO_REUSEPORT) if you require portability.

Improper use of SO_REUSEPORT may result in complex behavior and should only be used if you fully understand its implications (e.g., distributing incoming connections evenly across processes).

Parameters
[in]enableSet to true to enable SO_REUSEPORT, false to disable.
Exceptions
SocketExceptionif setting the option fails.
See also
https://man7.org/linux/man-pages/man7/socket.7.html

◆ setSendBufferSize()

void Socket::setSendBufferSize ( std::size_t size)

Sets the socket's send buffer size (SO_SNDBUF).

Configures the size of the operating system's send buffer for this socket. A larger buffer can improve performance for high-bandwidth connections by allowing the system to buffer more outgoing data, reducing the risk of blocking during write operations when the network is temporarily congested.

Implementation Details

  • Uses setsockopt() with SO_SNDBUF option to set kernel socket buffer size
  • The operating system may adjust the requested size:
    • Linux typically doubles the value to account for bookkeeping overhead
    • Windows may round to system-specific boundaries
    • Maximum size is limited by system settings (/proc/sys/net/core/wmem_max on Linux)
  • Changes affect subsequent sends only, not data already in the buffer
  • System limits may constrain maximum size based on available memory and OS policy

Example Usage

Socket sock("example.com", 80);
// Set 64KB send buffer
sock.setSendBufferSize(64 * 1024);
// Verify actual size (may be different)
int actualSize = sock.getSendBufferSize();
std::cout << "Actual send buffer size: " << actualSize << " bytes\n";
Parameters
[in]sizeDesired send buffer size in bytes. The actual size allocated may be adjusted by the operating system.
Exceptions
SocketExceptionIf:
  • Socket is invalid
  • System call fails
  • Requested size exceeds system limits
  • Insufficient permissions
Note
Some systems may double the specified size internally. Use getSendBufferSize() to verify the actual size.
See also
getReceiveBufferSize() Get current receive buffer size
setReceiveBufferSize() Set receive buffer size
getSendBufferSize() Get current send buffer size

◆ setSoTimeout() [1/2]

void jsocketpp::ServerSocket::setSoTimeout ( const int timeoutMillis)
inline

Set the logical timeout (in milliseconds) for accepting client connections.

This timeout applies to methods like accept() and tryAccept(), and determines how long the server socket will wait for a client connection before timing out.

Unlike Socket::setSoTimeout(), this method does not call setsockopt() and does not affect the underlying socket descriptor. Instead, it is used internally to control the behavior of select() during accept operations.

Note
Use:
  • Negative value: wait indefinitely (blocking behavior)
  • Zero: poll mode (non-blocking)
  • Positive value: wait up to the specified milliseconds
Parameters
timeoutMillisTimeout value in milliseconds
See also
getSoTimeout()
accept()
tryAccept()
waitReady()

◆ setSoTimeout() [2/2]

void Socket::setSoTimeout ( int millis,
bool forRead = true,
bool forWrite = true )

Set timeout for socket send and/or receive operations.

Configures timeouts for socket operations, allowing fine-grained control over how long the socket will wait during blocking send or receive operations before failing. This provides an alternative to non-blocking mode for handling slow or unresponsive peers.

Timeout Behavior

  • Read timeout (SO_RCVTIMEO): Maximum time to wait for incoming data
  • Write timeout (SO_SNDTIMEO): Maximum time to wait when sending data
  • Zero timeout: Operations return immediately if they would block
  • Negative timeout: Blocking mode (wait indefinitely)

Implementation Details

  • Uses setsockopt() with SO_RCVTIMEO and/or SO_SNDTIMEO
  • Platform-independent millisecond resolution
  • Affects all subsequent operations until changed
  • Thread-safe with respect to other Socket instances

Example Usage

Socket sock("example.com", 8080);
sock.connect();
// Set 5-second timeout for both read/write
sock.setSoTimeout(5000);
try {
// Will fail if no data received within 5 seconds
std::string data = sock.read<std::string>();
} catch (const SocketException& ex) {
if (ex.getErrorCode() == ETIMEDOUT) {
// Handle timeout
}
}
Parameters
[in]millisTimeout duration in milliseconds:
  • > 0: Maximum wait time
  • 0: Non-blocking operation
  • < 0: Blocking operation (no timeout)
[in]forReadIf true, set receive timeout (default: true)
[in]forWriteIf true, set send timeout (default: true)
Exceptions
SocketExceptionIf:
  • Socket is invalid (EBADF)
  • Permission denied (EACCES)
  • Invalid timeout value
  • System-specific errors
See also
setNonBlocking() Alternative approach for non-blocking operations
waitReady() For fine-grained operation timing
read() Affected by receive timeout
write() Affected by send timeout

◆ 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
    • Equivalent to calling shutdown() with Read and Write modes
    • Most similar to close() but keeps socket descriptor valid

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:294
@ Both
Shutdown both read and write operations (SHUT_RDWR or SD_BOTH)
Definition common.hpp:295

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., _sockFd = 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 (_sockFd = 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,
std::size_t sendBufferSize,
std::size_t internalBufferSize )
protected

Protected constructor used internally to create Socket objects for accepted client connections.

This constructor is specifically designed to be called by ServerSocket::accept() and related methods to create Socket instances representing established client connections. It initializes a Socket using an already-connected socket descriptor and the peer's address, and configures internal buffers and socket options for subsequent I/O.

Usage Flow

  1. ServerSocket::accept() receives a new client connection from the OS
  2. This constructor is invoked to create a Socket representing that client
  3. The Socket takes ownership of the connected socket descriptor and sets buffer sizes
  4. The constructed Socket is returned to the caller of accept()
Parameters
[in]clientSocket descriptor obtained from a successful accept() call.
[in]addrRemote peer address (sockaddr_storage for IPv4/IPv6 compatibility).
[in]lenSize of the peer address structure (sockaddr_in, sockaddr_in6, etc.).
[in]recvBufferSizeSize in bytes for the internal receive buffer and the socket's SO_RCVBUF.
[in]sendBufferSizeSize in bytes for the socket's SO_SNDBUF buffer.
[in]internalBufferSizeSize of the internal buffering layer used for string-based and stream reads.
Exceptions
SocketExceptionIf the socket options cannot be set or internal buffer allocation fails.
Note
This constructor is protected and only accessible to ServerSocket to ensure encapsulated and consistent initialization of accepted client connections.
See also
ServerSocket::accept() Creates Socket instances using this constructor.

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

Creates a new Socket object configured to connect to the specified host and port.

This constructor initializes a Socket object for a TCP connection to a remote host. It performs hostname resolution using getaddrinfo() to support both IPv4 and IPv6 addresses, creates the socket, and configures internal and socket-level buffer sizes.

Note: This constructor does not establish a network connection. You must explicitly call connect() after construction to initiate the TCP handshake.

Initialization Flow

  1. Resolves the target host using getaddrinfo() (DNS or IP)
  2. Creates the socket using the appropriate address family and protocol
  3. Applies the provided buffer sizes (or defaults if omitted)
Parameters
[in]hostThe remote hostname or IP address (e.g., "example.com", "127.0.0.1", "::1").
[in]portThe TCP port number to connect to (range: 1–65535).
[in]recvBufferSizeSocket-level receive buffer size (SO_RCVBUF). Defaults to DefaultBufferSize (4096 bytes).
[in]sendBufferSizeSocket-level send buffer size (SO_SNDBUF). Defaults to DefaultBufferSize (4096 bytes).
[in]internalBufferSizeSize of the internal buffer used for high-level read<T>() operations. This is distinct from the kernel socket buffers. Defaults to `DefaultBufferSize (4096 bytes).
Exceptions
SocketExceptionIf hostname resolution fails, socket creation fails, or buffer configuration fails.
Note
This constructor only prepares the socket. Use connect() to establish the actual connection.
See also
connect()
DefaultBufferSize
setReceiveBufferSize()
setSendBufferSize()
setInternalBufferSize()

◆ 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 ) const
nodiscard

Attempt to accept an incoming client connection, waiting up to a specified timeout.

This method waits for an incoming client connection using the provided timeoutMillis value, overriding any global timeout set with setSoTimeout(). If timeoutMillis is negative, the method blocks indefinitely until a client connects. If timeoutMillis is zero, the method polls and returns immediately if no client is waiting.

Unlike accept(int timeoutMillis, ...), which throws a SocketTimeoutException if the timeout expires, this method returns std::nullopt in that case. This makes it ideal for polling loops or event-driven servers.

Internally, this method uses waitReady(timeoutMillis) (via select()) to check for connection readiness. If the socket is ready, acceptBlocking(...) is called to retrieve the connection. Otherwise, std::nullopt is returned.

The blocking or non-blocking mode of the server socket (via setNonBlocking(true)) does not affect the behavior of this method. Readiness is determined exclusively via select(). However, due to inherent race conditions in all socket APIs, it’s still possible for accept() to fail with EWOULDBLOCK or EAGAIN after readiness has been reported. In such cases, a SocketException is thrown.

Note
This method is not thread safe. Protect server socket access externally if used from multiple threads.
Parameters
[in]timeoutMillisTimeout in milliseconds to wait for a client connection:
  • Negative: block indefinitely
  • Zero: poll once
  • Positive: wait up to this many milliseconds
[in]recvBufferSizeThe receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize().
[in]sendBufferSizeThe send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize().
[in]internalBufferSizeThe internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize().
Returns
std::optional<Socket> containing a client connection if accepted, or std::nullopt on timeout.
Exceptions
SocketExceptionif the server socket is invalid, closed, or an internal error occurs.
Precondition
Server socket must be valid, bound, and listening.
Postcondition
Returns std::nullopt if timeout expires; otherwise a connected Socket.
See also
accept()
tryAccept()
acceptBlocking()
acceptNonBlocking()
waitReady()
server.bind();
server.listen();
while (true) {
if (auto client = server.tryAccept(100)) {
// Handle client connection
} else {
// No client yet; continue polling
}
}

◆ 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 ) const
nodiscard

Attempt to accept an incoming client connection, returning immediately or after the configured timeout.

This method waits for an incoming client connection using the timeout set by setSoTimeout(). If no timeout is configured (i.e., negative value), the method blocks indefinitely until a client connects. If the timeout is zero, the method polls and returns immediately if no client is waiting.

Unlike accept(), this method does not throw a SocketTimeoutException if no client is available. Instead, it returns std::nullopt. This makes it suitable for event loops or non-blocking server designs.

Internally, this method uses waitReady() (which uses select()) to check for pending connections. If a client is ready, acceptBlocking() is called to retrieve the connection. If not, std::nullopt is returned.

The blocking or non-blocking mode of the server socket (via setNonBlocking()) does not affect the waiting behavior of this method, since select() is used for readiness. In rare cases, accept() may still fail with EWOULDBLOCK or EAGAIN if the connection is lost between readiness check and accept call, in which case a SocketException is thrown.

Note
This method is not thread safe. Simultaneous calls from multiple threads or processes may lead to race conditions. See accept() for a discussion of those edge cases.
To specify a timeout for a single call, use tryAccept(int timeoutMillis, ...).
This method uses the logical timeout configured via setSoTimeout() and does not rely on kernel-level socket timeouts. To control socket-level I/O timeout (for client sockets), see Socket::setSoTimeout().
Parameters
[in]recvBufferSizeThe receive buffer size (SO_RCVBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setReceiveBufferSize().
[in]sendBufferSizeThe send buffer size (SO_SNDBUF) to apply to the accepted socket. Defaults to DefaultBufferSize. Can also be set via setSendBufferSize().
[in]internalBufferSizeThe internal buffer size used by the accepted socket for read<T>() operations. Defaults to DefaultBufferSize. Can also be set via setDefaultInternalBufferSize().
Returns
An std::optional<Socket> containing the accepted client socket, or std::nullopt if no client was available before the timeout.
Exceptions
SocketExceptionif the server socket is not initialized, closed, or if an internal error occurs.
Precondition
Server socket must be valid, bound, and listening.
Postcondition
Returns std::nullopt if timeout expires, or a connected Socket on success.
See also
setSoTimeout(int)
getSoTimeout()
accept()
tryAccept(int, std::optional<std::size_t>, std::optional<std::size_t>)
acceptBlocking()
waitReady()
server.bind();
server.listen();
server.setSoTimeout(100); // Poll every 100 ms for new clients
while (true) {
if (auto client = server.tryAccept()) {
// Handle client...
} else {
// No client ready yet; perform other tasks or continue loop
}
}

◆ waitReady()

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

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

This method blocks until the server socket is ready to accept a new client connection, using an optional timeout. It is used internally by accept() and tryAccept(), and can also be used directly in custom wait loops.

Platform Behavior

  • POSIX: Uses poll() for readiness notification, avoiding select() limitations (like FD_SETSIZE).
  • Windows: Uses select() for compatibility and reliability across all socket types.

Timeout Semantics

  • If timeoutMillis < 0, the call blocks indefinitely.
  • If timeoutMillis == 0, the call polls and returns immediately.
  • If timeoutMillis > 0, it waits up to the specified time in milliseconds.
  • If no value is provided, the method uses the server socket's logical timeout as configured by setSoTimeout().
Note
This method does not use or affect kernel-level socket timeouts (SO_RCVTIMEO). It relies purely on event polling with poll() or select() and your configured logical timeout.

Thread Safety

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

Parameters
[in]timeoutMillisOptional timeout in milliseconds. Defaults to the value set by setSoTimeout().
Returns
true if the socket is ready to accept a connection, false if the timeout expired.
Exceptions
SocketExceptionif the socket is uninitialized or if a system error occurs during readiness check.
See also
accept(), tryAccept(), setSoTimeout(), getSoTimeout()

◆ write()

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

Writes data to the socket, handling partial writes.

Attempts to write the provided string data to the connected socket. This method may perform a partial write, meaning not all data may be sent in a single call. The return value indicates exactly how many bytes were successfully written.

Implementation Details

  • Uses send() system call internally
  • Handles platform differences (Windows/POSIX)
  • May write fewer bytes than requested
  • Does not retry on partial writes

Example Usage

Socket sock("example.com", 80);
sock.connect();
std::string msg = "Hello, server!";
size_t sent = sock.write(msg);
if (sent < msg.length()) {
// Handle partial write
std::cout << "Only sent " << sent << " of " << msg.length() << " bytes\n";
}
Parameters
[in]messageThe string data to send. Can contain binary data (including null bytes).
Returns
The number of bytes actually written to the socket. May be less than message.length() for partial writes.
Exceptions
SocketExceptionIf:
  • Socket is not connected (ENOTCONN)
  • Network error occurs (ENETDOWN, EPIPE)
  • Buffer is full and socket is blocking (EWOULDBLOCK)
  • Other system-specific errors
Note
[[nodiscard]] is used because ignoring the return value may lead to data loss if only part of the message was sent. Always check the return value against message.length().
See also
writeAll() To ensure complete message transmission
read() For receiving data
setSoTimeout() To set write timeout
setNonBlocking() To control blocking behavior

◆ writeAll()

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

Writes the entire contents of a message to the socket, handling partial writes.

Ensures that the complete message is transmitted by handling partial writes and retrying until all data is sent or an error occurs. This method is particularly useful when dealing with large messages that may require multiple write operations.

Implementation Details

  • Uses write() internally for actual socket operations
  • Tracks remaining data and offset for partial writes
  • Continues writing until all data is sent
  • Handles platform differences (Windows/POSIX)

Example Usage

Socket sock("example.com", 80);
sock.connect();
std::string msg = "Hello, server!";
try {
size_t sent = sock.writeAll(msg);
std::cout << "Successfully sent all " << sent << " bytes\n";
} catch (const SocketException& ex) {
std::cerr << "Failed to send complete message: " << ex.what() << '\n';
}
Parameters
[in]messageThe data to send. Can contain binary data (including null bytes).
Returns
The total number of bytes written (always equal to message.length() on success)
Exceptions
SocketExceptionIf:
  • Socket is not connected (ENOTCONN)
  • Network error occurs (ENETDOWN, EPIPE)
  • Connection is lost during transmission
  • Other system-specific errors
Note
This method will block until either:
  • All data is successfully written
  • An error occurs
  • The socket timeout is reached (if configured)
See also
write() For single-attempt writes that may be partial
setSoTimeout() To set write timeout
setNonBlocking() To control blocking behavior
isConnected() To check connection 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 for the socket to become writable, then attempts a single send() of up to data.size() bytes. This method does not retry. It is suitable for time-sensitive or polling-based write loops.

Implementation Details

  • Uses waitReady(true, timeoutMillis) once
  • Calls send() once to write as much as possible
  • Returns the number of bytes actually written

Example Usage

std::string payload = "POST /data";
std::size_t sent = sock.writeAtMostWithTimeout(payload, 500);
Parameters
dataThe data to send.
timeoutMillisThe maximum time to wait before sending.
Returns
The number of bytes written (can be 0).
Exceptions
SocketExceptionIf:
  • Timeout occurs before socket becomes writable
  • send() fails
  • Connection is closed
Note
This is a best-effort, low-latency write. Use writeAll() or writeWithTimeoutRetry() for full delivery.
See also
readAtMostWithTimeout()
writeAll()

◆ 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
dataPointer to the memory to write.
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
dataPointer to the binary buffer to send.
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 & payload)
inline

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

Sends a message that consists of a length prefix followed by the actual payload. The prefix type T determines the format and size of the length field and is written in network byte order for cross-platform interoperability.

Implementation Details

  • The payload length is first cast to T (must not exceed max representable value)
  • The prefix is converted to network byte order using net::toNetwork()
  • The prefix is written first, followed immediately by the raw payload
  • Accepts either std::string or raw (void*, size) overloads

Example Usage

Socket sock("example.com", 8080);
sock.connect();
std::string 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 a trivially copyable type.
Parameters
payloadThe string data to send. The length of this string will be encoded as the prefix and must not exceed the maximum value of type T.
Returns
The total number of bytes written (prefix + payload).
Exceptions
SocketExceptionIf:
  • Writing the prefix or payload fails
  • Payload length exceeds max value representable by T
  • The connection is closed or interrupted
Note
The prefix is automatically converted to network byte order using jsocketpp::net::toNetwork(). The receiver must decode the prefix using readPrefixed<T>() or equivalent logic.
See also
readPrefixed() To decode the corresponding message
writeFromAll() To write raw binary data without a 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
dataPointer to the binary payload data.
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
  • 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
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
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
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
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 as needed to ensure that all bytes are delivered within the specified timeout window. Fails if not all buffers can be sent before the timeout expires.

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()}
};
sock.writevFromWithTotalTimeout(bufs, 2000); // must finish in 2s
Parameters
buffersA span of raw memory buffers to fully write.
timeoutMillisTotal timeout in milliseconds across all retries.
Returns
Total bytes written (equal to sum of buffer sizes on success).
Exceptions
SocketExceptionIf:
  • The timeout expires before all data is written
  • The socket becomes unwritable
  • Connection is closed prematurely
Note
This is the binary-buffer equivalent of writevWithTotalTimeout().
See also
writevFromAll() For blocking, unbounded version
writevWithTotalTimeout() For string_view variant

◆ 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 given span using scatter/gather I/O. Retries on partial sends until either all buffers are sent or the timeout expires. This is the timeout-aware counterpart to writevAll().

Implementation Details

  • Uses a std::chrono::steady_clock deadline internally
  • Each iteration waits for socket writability using remaining time
  • Uses writev() to transmit multiple buffers at once
  • Rebuilds the span as needed to resume after partial sends

Example Usage

std::array<std::string_view, 3> parts = {
"Header: ",
"value\r\n\r\n",
"Body content"
};
sock.writevWithTotalTimeout(parts, 1500);
Parameters
buffersA span of buffers to send in order.
timeoutMillisMaximum total time allowed for the operation, in milliseconds.
Returns
Total number of bytes sent (equal to the sum of buffer sizes on success).
Exceptions
SocketExceptionIf:
  • The timeout expires before full delivery
  • A network or socket error occurs
  • The connection is closed prematurely
Note
This method guarantees atomic full delivery within a strict time budget. Use writevAll() if timeout control is not needed.
See also
writevAll() For unbounded full delivery
writeWithTotalTimeout() For single-buffer variant

◆ 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 write all bytes from data, retrying partial writes as needed. The entire operation must complete within timeoutMillis milliseconds. If the timeout expires before all data is sent, the method throws a SocketException.

Implementation Details

  • Uses a std::chrono::steady_clock deadline internally
  • Each iteration waits for socket writability using remaining time
  • Behaves like writeAll() but bounded by a total wall-clock timeout

Example Usage

std::string json = buildPayload();
sock.writeWithTotalTimeout(json, 1000); // Must finish in 1 second
Parameters
dataThe data to send.
timeoutMillisMaximum total duration (in milliseconds) to complete the operation.
Returns
Total number of bytes written (equals data.size() on success).
Exceptions
SocketExceptionIf:
  • The timeout expires before full delivery
  • A network or socket error occurs
  • Connection is closed during send
Note
This is the timeout-aware counterpart to writeAll(). Prefer this when responsiveness or time-bound delivery is required.
See also
writeAll() For unbounded full delivery
writeAtMostWithTimeout() For best-effort single attempt

◆ ~ServerSocket()

ServerSocket::~ServerSocket ( )
noexcept

Destructor that automatically closes the server socket and releases all associated resources.

This destructor ensures proper cleanup of system resources when a ServerSocket object is destroyed:

  • 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 ( )
noexcept

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