Implementation-only utilities for internal use.
More...
|
| namespace | jsocketpp::internal |
| | Implementation-only utilities and platform abstractions for jsocketpp.
|
|
| std::vector< WSABUF > | jsocketpp::internal::toWSABUF (const BufferView *buffers, const std::size_t count) |
| | Convert a raw array of BufferView elements into a WSABUF array for use with Windows socket APIs.
|
| std::vector< WSABUF > | jsocketpp::internal::toWSABUF (const std::span< const BufferView > buffers) |
| | Convert a span of BufferView elements into a WSABUF array (Windows).
|
| std::vector< iovec > | jsocketpp::internal::toIOVec (const BufferView *buffers, const std::size_t count) |
| | Convert a raw array of BufferView elements into an iovec array for POSIX readv/writev.
|
| std::vector< iovec > | jsocketpp::internal::toIOVec (const std::span< const BufferView > buffers) |
| | Convert a span of BufferView elements into an iovec array for POSIX vectorized I/O.
|
| AddrinfoPtr | jsocketpp::internal::resolveAddress (const std::string_view host, const Port port, const int family, const int socktype, const int protocol, const int flags=0) |
| | Resolves a hostname and port into a list of usable socket address structures.
|
| std::string | jsocketpp::internal::getBoundLocalIp (SOCKET sockFd) |
| | Retrieves the local IP address to which the socket is currently bound.
|
| void | jsocketpp::internal::sendExact (SOCKET fd, const void *data, std::size_t size) |
| | Sends an entire datagram to a connected peer using send().
|
| void | jsocketpp::internal::sendExactTo (SOCKET fd, const void *data, std::size_t size, const sockaddr *addr, socklen_t addrLen, void(*afterSuccess)(void *ctx), void *ctx) |
| | Sends an entire datagram to a specific destination using sendto().
|
| bool | jsocketpp::internal::tryCloseNoexcept (const SOCKET fd) noexcept |
| | Attempts to close a socket descriptor without throwing exceptions.
|
| void | jsocketpp::internal::closeOrThrow (const SOCKET fd) |
| | Closes a socket descriptor and throws on failure.
|
| | jsocketpp::internal::ScopedBlockingMode::ScopedBlockingMode (const SOCKET sock, bool temporaryNonBlocking) |
| | Construct a ScopedBlockingMode that temporarily overrides the socket's blocking mode.
|
| | jsocketpp::internal::ScopedBlockingMode::~ScopedBlockingMode () |
| | Restore the socket's original blocking mode on destruction.
|
Implementation-only utilities for internal use.
These functions and types are not part of the public API. They are intended for internal glue code, platform compatibility, and cross-cutting concerns.
- Warning
- Do not rely on this module from user code. It is subject to change without notice.
◆ AddrinfoPtr
Smart pointer that manages addrinfo* resources using AddrinfoDeleter.
AddrinfoPtr wraps a raw addrinfo* (typically from getaddrinfo()) in a std::unique_ptr with a custom deleter to ensure safe, automatic cleanup using freeaddrinfo(). This eliminates manual memory management and guards against memory leaks in error-prone network code.
Example Usage
addrinfo* raw = nullptr;
if (getaddrinfo("example.com", "80", &hints, &raw) == 0) {
}
std::unique_ptr< addrinfo, AddrinfoDeleter > AddrinfoPtr
Smart pointer that manages addrinfo* resources using AddrinfoDeleter.
Definition common.hpp:819
- See also
- AddrinfoDeleter
-
getaddrinfo()
-
freeaddrinfo()
◆ closeOrThrow()
| void jsocketpp::internal::closeOrThrow |
( |
const SOCKET | fd | ) |
|
|
inline |
Closes a socket descriptor and throws on failure.
This helper attempts to close the specified socket descriptor using the platform‐specific CloseSocket() function. If the descriptor is invalid (INVALID_SOCKET), the function returns immediately without error.
If CloseSocket() fails, the function retrieves the platform error code via GetSocketError() and throws a SocketException containing both the numeric error and a descriptive message produced by SocketErrorMessage(error).
This function is intended for use in public close() methods or other contexts where socket closure errors must be explicitly reported to the caller.
- Parameters
-
| [in] | fd | The platform‐specific socket descriptor to close. If set to INVALID_SOCKET, no action is taken. |
- Exceptions
-
| SocketException | If closing the socket fails, with the platform error code and message. |
- Note
- This function may throw. For destructors or cleanup routines where exceptions are not allowed, use tryCloseNoexcept() instead.
void MySocket::close() {
}
void closeOrThrow(const SOCKET fd)
Closes a socket descriptor and throws on failure.
Definition common.hpp:1244
constexpr SOCKET INVALID_SOCKET
Definition common.hpp:264
◆ getBoundLocalIp()
| std::string jsocketpp::internal::getBoundLocalIp |
( |
SOCKET | sockFd | ) |
|
|
nodiscard |
Retrieves the local IP address to which the socket is currently bound.
This function returns the numeric IP address of the socket's local endpoint, based on the actual binding or connection state. It supports both IPv4 and IPv6 sockets.
🔧 Internal Mechanism
This method wraps two low-level system calls:
- getsockname(): Obtains the local address (IP and port) that the socket is bound to. This works regardless of whether the socket was explicitly bound (bind()) or implicitly assigned a source address via connect() or sendto() on unconnected sockets.
- getnameinfo(): Converts the raw sockaddr structure returned by getsockname() into a numeric IP string (e.g., "127.0.0.1" or "::1"), independent of DNS.
✅ Use Cases
- Discover which local interface the OS selected after bind() or connect()
- Match the socket to a network adapter for MTU queries or interface statistics
- Print the socket’s local IP address for diagnostics or logging
- Support systems where multiple NICs or address families are in use
⚠️ Error Handling
- Throws SocketException if the socket is not open, not yet bound, or if address resolution fails.
- All errors include system-specific error codes and human-readable descriptions.
- Parameters
-
| [in] | sockFd | The socket descriptor (SOCKET on Windows, int on POSIX). |
- Returns
- A string containing the numeric IPv4 or IPv6 address the socket is bound to.
- Exceptions
-
| SocketException | If:
- The socket is invalid or unbound
- getsockname() fails (e.g., bad descriptor)
- getnameinfo() fails (e.g., unsupported address format)
|
- Note
- This function does not return the remote peer address — use getpeername() for that.
-
This function does not include the port — only the IP address portion is returned.
- See also
- getLocalSocketAddress(), getpeername(), resolveAddress(), getMTU()
◆ resolveAddress()
| AddrinfoPtr jsocketpp::internal::resolveAddress |
( |
const std::string_view | host, |
|
|
const Port | port, |
|
|
const int | family, |
|
|
const int | socktype, |
|
|
const int | protocol, |
|
|
const int | flags = 0 ) |
|
inlinenodiscard |
Resolves a hostname and port into a list of usable socket address structures.
This internal helper wraps the standard ::getaddrinfo() system call to resolve a hostname and port into a linked list of addrinfo structures, which are used to create, bind, or connect sockets. It provides explicit control over resolution parameters, supports both client and server use cases, and ensures consistent error handling and memory cleanup across platforms.
Overview
Unlike direct getaddrinfo() usage, this helper:
- Accepts all key resolution parameters (family, socktype, protocol, flags)
- Returns a RAII-managed AddrinfoPtr (automatically frees memory via freeaddrinfo())
- Throws a SocketException with detailed context if resolution fails
- Supports dual-stack fallback, wildcard binding, strict numeric resolution, and more
Hints Structure Behavior
This function populates the hints structure for getaddrinfo() with the following fields:
- ai_family: Address family to return:
- AF_INET — IPv4 only
- AF_INET6 — IPv6 only
- AF_UNSPEC — Return both (default for dual-stack logic)
- ai_socktype: Type of socket:
- SOCK_STREAM — TCP
- SOCK_DGRAM — UDP
- SOCK_RAW — Raw IP (less common)
- ai_protocol: Transport-layer protocol:
- IPPROTO_TCP — for TCP sockets
- IPPROTO_UDP — for UDP sockets
- 0 — auto-detect based on socktype
- ai_flags: Bitmask of resolution modifiers. Includes:
- AI_PASSIVE — Use wildcard address (0.0.0.0 / ::) if host is empty (for server binding)
- AI_NUMERICHOST — Require host to be a numeric IP; skip DNS
- AI_NUMERICSERV — Require port to be numeric; skip service name lookup
- AI_CANONNAME — Populate ai_canonname with canonical FQDN
- AI_ADDRCONFIG — Only return families configured on the local machine
- AI_V4MAPPED — Allow IPv4-mapped IPv6 addresses if AF_INET6 is requested
Flags may be combined using bitwise OR (e.g., AI_PASSIVE | AI_ADDRCONFIG).
Parameters
- Parameters
-
| [in] | host | Hostname, domain, or IP address to resolve.
- Use empty string if AI_PASSIVE is set to bind to all interfaces.
- Must be numeric if AI_NUMERICHOST is specified.
|
| [in] | port | Port number to resolve, passed as an integer. Must be in the range [0, 65535]. Internally converted to a string before calling getaddrinfo(). |
| [in] | family | Address family to restrict the result:
- AF_INET for IPv4
- AF_INET6 for IPv6
- AF_UNSPEC for both (default in most client cases)
|
| [in] | socktype | Desired socket type (e.g., SOCK_STREAM, SOCK_DGRAM) |
| [in] | protocol | Desired protocol (e.g., IPPROTO_TCP, IPPROTO_UDP, or 0) |
| [in] | flags | Bitmask of AI_* flags. See the list above for all supported options. |
Return Value
- Returns
- A smart pointer of type AddrinfoPtr holding a linked list of addrinfo structures. The returned list can be iterated to attempt socket creation or connection. Memory is released automatically via freeaddrinfo() when the pointer is destroyed.
Throws
- Exceptions
-
| SocketException | if getaddrinfo() fails.
- On Windows: error code from GetSocketError(), with message from gai_strerror()
- On POSIX: return code from getaddrinfo(), also with gai_strerror() message
- The error message will include whether the failure occurred on the host or service name
|
Example Usage
auto addrList =
resolveAddress(
"example.com", 443, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
for (addrinfo* p = addrList.get(); p != nullptr; p = p->ai_next)
{
int sockfd = ::socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (sockfd !=
INVALID_SOCKET && ::connect(sockfd, p->ai_addr, p->ai_addrlen) == 0)
break;
}
AddrinfoPtr resolveAddress(const std::string_view host, const Port port, const int family, const int socktype, const int protocol, const int flags=0)
Resolves a hostname and port into a list of usable socket address structures.
Definition common.hpp:946
Implementation-only utilities and platform abstractions for jsocketpp.
Definition BufferView.hpp:52
Notes
- This function is intended for internal use by Socket, ServerSocket, and DatagramSocket.
- It supports both binding (server-side) and connecting (client-side) resolution logic.
- Always use AF_UNSPEC and let getaddrinfo() return both IPv4 and IPv6 for best cross-platform support.
- See also
- getaddrinfo(), freeaddrinfo(), AddrinfoPtr, SocketException
◆ ScopedBlockingMode()
| jsocketpp::internal::ScopedBlockingMode::ScopedBlockingMode |
( |
const SOCKET | sock, |
|
|
bool | temporaryNonBlocking ) |
|
inline |
Construct a ScopedBlockingMode that temporarily overrides the socket's blocking mode.
This constructor queries the current blocking state of the specified socket and sets it to the desired temporary mode (blocking or non-blocking). Upon destruction, the original mode is restored.
This is typically used to safely override a socket's mode during a scoped operation (e.g. non-blocking connect()), without permanently modifying the socket's configuration.
- Parameters
-
| sock | The native socket descriptor (platform-specific type: SOCKET on Windows, int on POSIX). |
| temporaryNonBlocking | If true, the socket will be set to non-blocking mode during the scope. If false, it will be temporarily set to blocking mode. |
- Exceptions
-
| std::runtime_error | if querying or setting the socket mode fails. |
- Note
- The constructor reads the current mode and only applies a change if necessary.
-
If setNonBlocking() is called on the same socket while the object is alive, the final restored state may be incorrect.
- See also
- ~ScopedBlockingMode()
-
setNonBlocking()
◆ sendExact()
| void jsocketpp::internal::sendExact |
( |
SOCKET | fd, |
|
|
const void * | data, |
|
|
std::size_t | size ) |
Sends an entire datagram to a connected peer using send().
This internal utility transmits exactly size bytes from the given data buffer over the specified socket fd, using the system send() call. It is intended for use with connected UDP or TCP sockets where the destination address is already established via connect().
⚙️ Behavior
- Applies MSG_NOSIGNAL on POSIX systems to prevent SIGPIPE if the peer has closed the connection.
- Casts the buffer size appropriately for Windows (int) and POSIX (size_t) APIs.
- On success, guarantees that all
size bytes are sent in a single system call.
- Throws an exception if:
- The socket is invalid (INVALID_SOCKET)
- send() fails for any reason
- The number of bytes actually sent differs from
size (partial send)
🧪 Example
std::string message = "Hello, world!";
void sendExact(SOCKET fd, const void *data, std::size_t size)
Sends an entire datagram to a connected peer using send().
Definition common.cpp:477
- Parameters
-
| [in] | fd | The connected socket file descriptor to send data on. |
| [in] | data | Pointer to the raw buffer containing data to transmit. |
| [in] | size | Number of bytes to send from data. |
- Exceptions
-
| SocketException | If the socket is invalid, if send() returns an error, or if a partial datagram is sent. |
- Warning
- This function does not perform retries or fragmentation. For UDP, datagrams larger than the network MTU may be dropped.
-
Intended for internal use — use higher-level write() APIs instead in application code.
- See also
- sendExactTo() For sending to an explicit address without connecting first.
-
connect() To establish a connected peer before using this function.
◆ sendExactTo()
| void jsocketpp::internal::sendExactTo |
( |
SOCKET | fd, |
|
|
const void * | data, |
|
|
std::size_t | size, |
|
|
const sockaddr * | addr, |
|
|
socklen_t | addrLen, |
|
|
void(* | afterSuccess )(void *ctx), |
|
|
void * | ctx ) |
Sends an entire datagram to a specific destination using sendto().
This internal utility transmits exactly size bytes from the given data buffer over the specified socket fd, using the system sendto() call to send to an explicit destination address. It is intended for unconnected UDP sockets, where the destination may vary per call.
⚙️ Behavior
- Applies MSG_NOSIGNAL on POSIX systems to prevent SIGPIPE if the destination is unreachable or the peer has closed the socket.
- Casts the buffer size and address length appropriately for Windows (int) and POSIX (size_t, socklen_t) APIs.
- On success, guarantees that all
size bytes are sent in a single system call.
- Throws an exception if:
- The socket is invalid (INVALID_SOCKET)
- sendto() fails for any reason
- The number of bytes actually sent differs from
size (partial send)
🧪 Example
sockaddr_storage destAddr{};
reinterpret_cast<const sockaddr*>(&destAddr),
sizeof(sockaddr_in));
void sendExactTo(SOCKET fd, const void *data, std::size_t size, const sockaddr *addr, socklen_t addrLen, void(*afterSuccess)(void *ctx), void *ctx)
Sends an entire datagram to a specific destination using sendto().
Definition common.cpp:505
- Parameters
-
| [in] | fd | The socket file descriptor to send data on. |
| [in] | data | Pointer to the raw buffer containing data to transmit. |
| [in] | size | Number of bytes to send from data. |
| [in] | addr | Pointer to the destination address structure (IPv4 or IPv6). |
| [in] | addrLen | Length of the address structure in bytes. |
| [in] | afterSuccess | Optional callback invoked after a successful send (may be nullptr). |
| [in] | ctx | Opaque pointer passed to afterSuccess (e.g., this). |
- Exceptions
-
| SocketException | If the socket is invalid, if sendto() returns an error, or if a partial datagram is sent. |
- Warning
- This function does not perform retries or fragmentation. For UDP, datagrams larger than the network MTU may be dropped.
-
Intended for internal use — use higher-level writeTo() or write(DatagramPacket&) APIs instead in application code.
- See also
- sendExact() For sending to a connected peer without specifying an address.
-
writeTo() For type-safe per-call destination sends.
◆ toIOVec() [1/2]
| std::vector< iovec > jsocketpp::internal::toIOVec |
( |
const BufferView * | buffers, |
|
|
const std::size_t | count ) |
|
inlinenodiscard |
Convert a raw array of BufferView elements into an iovec array for POSIX readv/writev.
This function converts a contiguous C-style array of BufferView entries into a std::vector<iovec>, which can be passed directly to POSIX I/O functions like readv() and writev(). Each iovec will reflect the same memory range described by the corresponding BufferView.
- Parameters
-
| [in] | buffers | Pointer to a contiguous array of BufferView elements. |
| [in] | count | The number of elements in the input array. |
- Returns
- A std::vector<iovec> referencing the same memory regions.
- Note
- This function performs shallow conversion—no memory is copied.
-
Only available on non-Windows platforms (i.e., when _WIN32 is not defined).
- See also
- BufferView
-
iovec
-
readv()
-
writev()
◆ toIOVec() [2/2]
| std::vector< iovec > jsocketpp::internal::toIOVec |
( |
const std::span< const BufferView > | buffers | ) |
|
|
inlinenodiscard |
Convert a span of BufferView elements into an iovec array for POSIX vectorized I/O.
This overload transforms a std::span<const BufferView> into a std::vector<iovec>, which is suitable for use with POSIX APIs such as readv() and writev().
- Parameters
-
- Returns
- A std::vector<iovec> referencing the same memory described by the span.
- Note
- This function performs shallow conversion—no memory is copied.
-
Only available on non-Windows platforms (i.e., when _WIN32 is not defined).
- See also
- BufferView
-
iovec
-
toIOVec(const BufferView*, std::size_t)
-
readv()
-
writev()
◆ toWSABUF() [1/2]
| std::vector< WSABUF > jsocketpp::internal::toWSABUF |
( |
const BufferView * | buffers, |
|
|
const std::size_t | count ) |
|
inlinenodiscard |
Convert a raw array of BufferView elements into a WSABUF array for use with Windows socket APIs.
This utility function transforms a contiguous C-style array of BufferView structures into a std::vector<WSABUF>, suitable for use with Windows socket functions such as WSASend() and WSARecv(). Each WSABUF struct will point to the same memory region described by its corresponding BufferView.
- Parameters
-
| [in] | buffers | Pointer to a contiguous array of BufferView structures. |
| [in] | count | The number of elements in the buffers array. |
- Returns
- A std::vector<WSABUF> with one entry per buffer, preserving memory addresses and sizes.
- Note
- This function performs shallow conversion—no memory is copied.
-
This function is only available on Windows (_WIN32 defined).
- See also
- BufferView
-
WSABUF
-
WSASend()
-
WSARecv()
◆ toWSABUF() [2/2]
| std::vector< WSABUF > jsocketpp::internal::toWSABUF |
( |
const std::span< const BufferView > | buffers | ) |
|
|
inlinenodiscard |
Convert a span of BufferView elements into a WSABUF array (Windows).
This overload provides a convenient interface for converting a std::span<const BufferView> into a std::vector<WSABUF> for use with Windows socket APIs such as WSASend() and WSARecv().
- Parameters
-
| [in] | buffers | A std::span containing one or more BufferView elements. |
- Returns
- A std::vector<WSABUF> that references the same memory described by each BufferView.
- Note
- This function performs shallow conversion—no memory is copied.
-
This function is only available on Windows (_WIN32 defined).
- See also
- BufferView
-
WSABUF
-
toWSABUF(const BufferView*, std::size_t)
◆ tryCloseNoexcept()
| bool jsocketpp::internal::tryCloseNoexcept |
( |
const SOCKET | fd | ) |
|
|
inlinenoexcept |
Attempts to close a socket descriptor without throwing exceptions.
This helper performs a best-effort close of the given socket descriptor. It is specifically intended for use in destructors and cleanup routines where exception safety is critical and socket closure failures must not propagate.
If the descriptor is already invalid (INVALID_SOCKET), the function returns immediately with true.
On a valid descriptor, the underlying platform‐specific CloseSocket() is called. If it succeeds, the function returns true. If it fails, the error is silently ignored (per project close policy) and false is returned. Optional logging or diagnostics may be added at the marked location in the implementation if desired.
- Parameters
-
| [in] | fd | The platform‐specific socket descriptor to close. If set to INVALID_SOCKET, no action is taken. |
- Returns
- true if the socket was already invalid or successfully closed; false if closing failed (error is ignored).
- Note
- This function never throws. For public close() methods where errors must be reported, use a throwing variant such as closeOrThrow() instead.
~SocketWrapper() noexcept {
}
bool tryCloseNoexcept(const SOCKET fd) noexcept
Attempts to close a socket descriptor without throwing exceptions.
Definition common.hpp:1198
◆ ~ScopedBlockingMode()
| jsocketpp::internal::ScopedBlockingMode::~ScopedBlockingMode |
( |
| ) |
|
|
inline |
Restore the socket's original blocking mode on destruction.
This destructor attempts to revert the socket descriptor to the blocking mode it had at the time of this object's construction. This ensures that any temporary change to the blocking state (via the constructor) is automatically undone, preserving consistent socket behavior after the scope ends.
This restoration is performed even if an exception was thrown inside the guarded scope, making this class suitable for safe use in exception-prone paths such as connect() with timeout logic.
- Note
- Errors during restoration are silently ignored. This is intentional to maintain noexcept destructor semantics and prevent exceptions from escaping destructors.
- Warning
- Do not call setNonBlocking() on the same socket while a ScopedBlockingMode is active, as this will interfere with the mode restoration logic.
- See also
- ScopedBlockingMode()