18 Sockets [socket]

18.2 Requirements [socket.reqmts]

18.2.1 Requirements on synchronous socket operations [socket.reqmts.sync]

In this subclause, synchronous socket operations are those member functions specified as two overloads, with and without an argument of type error_code&:

R f(A1 a1, A2 a2, ..., AN aN);
R f(A1 a1, A2 a2, ..., AN aN, error_code& ec);

For an object s, the conditions under which its synchronous socket operations may block the calling thread (C++ 2014 [defns.block]) are determined as follows.

If:

  • s.non_blocking() == true,

  • the synchronous socket operation is specified in terms of a POSIX function other than poll,

  • that POSIX function lists EWOULDBLOCK or EAGAIN in its failure conditions, and

  • the effects of the operation cannot be established immediately

then the synchronous socket operation shall not block the calling thread. [ Note: And the effects of the operation are not established.  — end note ]

Otherwise, the synchronous socket operation shall block the calling thread until the effects are established.

18.2.2 Requirements on asynchronous socket operations [socket.reqmts.async]

In this subclause, asynchronous socket operations are those member functions having prefix async_.

For an object s, a program may initiate asynchronous socket operations such that there are multiple simultaneously outstanding asynchronous operations.

When there are multiple outstanding asynchronous read operations ([buffer.reqmts.read.write]) on s:

  • having no argument flags of type socket_base::message_flags, or

  • having an argument flags of type socket_base::message_flags but where (flags & socket_base::message_out_of_band) == 0

then the buffers are filled in the order in which these operations were issued. The order of invocation of the completion handlers for these operations is unspecified.

When there are multiple outstanding asynchronous read operations ([buffer.reqmts.read.write]) on s having an argument flags of type socket_base::message_flags where (flags & socket_base::message_out_of_band) != 0 then the buffers are filled in the order in which these operations were issued.

When there are multiple outstanding asynchronous write operations ([buffer.reqmts.read.write]) on s, the buffers are transmitted in the order in which these operations were issued. The order of invocation of the completion handlers for these operations is unspecified.

18.2.3 Native handles [socket.reqmts.native]

Several classes described in this document have a member type native_handle_type, a member function native_handle, and member functions that return or accept arguments of type native_handle_type. The presence of these members and their semantics is implementation-defined.

When an operation has its effects specified as if by passing the result of native_handle() to a POSIX function the effect is as if native_handle_type is the type int.

Note: These members allow implementations to provide access to their implementation details. Their names are specified to facilitate portable compile-time detection. Actual use of these members is inherently non-portable. For operating systems that are based on POSIX, implementations can define the native_handle_type for sockets as int, representing the native file descriptor associated with the socket.  — end note ]

18.2.4 Endpoint requirements [socket.reqmts.endpoint]

A type X meets the Endpoint requirements if it satisfies the requirements of Destructible (C++ 2014 [destructible]), DefaultConstructible (C++ 2014 [defaultconstructible]), CopyConstructible (C++ 2014 [copyconstructible]), and CopyAssignable (C++ 2014 [copyassignable]), as well as the additional requirements listed below.

In the table below, a denotes a (possibly const) value of type X, and u denotes an identifier.

Table 21 — Endpoint requirements
expressiontypeassertion/note pre/post-conditions
X::protocol_type type meeting Protocol ([socket.reqmts.protocol]) requirements
a.protocol() protocol_type

In the table below, a denotes a (possibly const) value of type X, b denotes a value of type X, and s denotes a (possibly const) value of a type that is convertible to size_t and denotes a size in bytes.

Table 22 — Endpoint requirements for extensible implementations
expressiontypeassertion/note pre/post-conditions
a.data() const void* Returns a pointer suitable for passing as the address argument to functions such as POSIX connect, or as the dest_addr argument to functions such as POSIX sendto. The implementation shall perform a static_cast on the pointer to convert it to const sockaddr*.
b.data() void* Returns a pointer suitable for passing as the address argument to functions such as POSIX accept, getpeername, getsockname and recvfrom. The implementation shall perform a static_cast on the pointer to convert it to sockaddr*.
a.size() size_t Returns a value suitable for passing as the address_len argument to functions such as POSIX connect, or as the dest_len argument to functions such as POSIX sendto, after appropriate integer conversion has been performed.
b.resize(s) pre: s >= 0
post: a.size() == s
Passed the value contained in the address_len argument to functions such as POSIX accept, getpeername, getsockname, and recvfrom, after successful completion of the function. Permitted to throw an exception if the protocol associated with the endpoint object a does not support the specified size.
a.capacity() size_t Returns a value suitable for passing as the address_len argument to functions such as POSIX accept, getpeername, getsockname, and recvfrom, after appropriate integer conversion has been performed.

18.2.5 Endpoint sequence requirements [socket.reqmts.endpointsequence]

A type X meets the EndpointSequence requirements if it satisfies the requirements of Destructible (C++ 2014 [destructible]) and CopyConstructible (C++ 2014 [copyconstructible]), as well as the additional requirements listed below.

In the table below, x denotes a (possibly const) value of type X.

Table 23 — EndpointSequence requirements
expressionreturn typeassertion/note pre/post-condition
x.begin()
x.end()
A type meeting the requirements for forward iterators (C++ 2014 [forward.iterators]) whose value type is convertible to a type satisfying the Endpoint ([socket.reqmts.endpoint]) requirements. [x.begin(), x.end()) is a valid range.

18.2.6 Protocol requirements [socket.reqmts.protocol]

A type X meets the Protocol requirements if it satisfies the requirements of Destructible (C++ 2014 [destructible]), CopyConstructible (C++ 2014 [copyconstructible]), and CopyAssignable (C++ 2014 [copyassignable]), as well as the additional requirements listed below.

Table 24 — Protocol requirements
expressionreturn typeassertion/note pre/post-conditions
X::endpoint type meeting endpoint ([socket.reqmts.endpoint]) requirements

In the table below, a denotes a (possibly const) value of type X.

Table 25 — Protocol requirements for extensible implementations
expressionreturn typeassertion/note pre/post-conditions
a.family() int Returns a value suitable for passing as the domain argument to POSIX socket (or equivalent).
a.type() int Returns a value suitable for passing as the type argument to POSIX socket (or equivalent).
a.protocol() int Returns a value suitable for passing as the protocol argument to POSIX socket (or equivalent).

18.2.7 Acceptable protocol requirements [socket.reqmts.acceptableprotocol]

A type X meets the AcceptableProtocol requirements if it satisfies the requirements of Protocol ([socket.reqmts.protocol]) as well as the additional requirements listed below.

Table 26 — AcceptableProtocol requirements
expressionreturn typeassertion/note pre/post-conditions
X::socket A type that satisfies the requirements of Destructible (C++ 2014 [destructible]) and MoveConstructible (C++ 2014 [moveconstructible]), and that is publicly and unambiguously derived from basic_socket<X>.

18.2.8 Gettable socket option requirements [socket.reqmts.gettablesocketoption]

A type X meets the GettableSocketOption requirements if it satisfies the requirements listed below.

In the table below, a denotes a (possibly const) value of type X, b denotes a value of type X, p denotes a value of a (possibly const) type that meets the Protocol ([socket.reqmts.protocol]) requirements, and s denotes a value of a (possibly const) type that is convertible to size_t and denotes a size in bytes.

Table 27 — GettableSocketOption requirements for extensible implementations
expressiontypeassertion/note pre/post-conditions
a.level(p) int Returns a value suitable for passing as the level argument to POSIX getsockopt (or equivalent).
a.name(p) int Returns a value suitable for passing as the option_name argument to POSIX getsockopt (or equivalent).
b.data(p) void* Returns a pointer suitable for passing as the option_value argument to POSIX getsockopt (or equivalent).
a.size(p) size_t Returns a value suitable for passing as the option_len argument to POSIX getsockopt (or equivalent), after appropriate integer conversion has been performed.
b.resize(p,s) post: b.size(p) == s. Passed the value contained in the option_len argument to POSIX getsockopt (or equivalent) after successful completion of the function. Permitted to throw an exception if the socket option object b does not support the specified size.

18.2.9 Settable socket option requirements [socket.reqmts.settablesocketoption]

A type X meets the SettableSocketOption requirements if it satisfies the requirements listed below.

In the table below, a denotes a (possibly const) value of type X, p denotes a (possibly const) value of a type that meets the Protocol ([socket.reqmts.protocol]) requirements, and u denotes an identifier.

Table 28 — SettableSocketOption requirements for extensible implementations
expressiontypeassertion/note pre/post-conditions
a.level(p) int Returns a value suitable for passing as the level argument to POSIX setsockopt (or equivalent).
a.name(p) int Returns a value suitable for passing as the option_name argument to POSIX setsockopt (or equivalent).
a.data(p) const void* Returns a pointer suitable for passing as the option_value argument to POSIX setsockopt (or equivalent).
a.size(p) size_t Returns a value suitable for passing as the option_len argument to POSIX setsockopt (or equivalent), after appropriate integer conversion has been performed.

18.2.10 Boolean socket options [socket.reqmts.opt.bool]

A type X meets the BooleanSocketOption requirements if it satisfies the requirements of Destructible (C++ 2014 [destructible]), DefaultConstructible (C++ 2014 [defaultconstructible]), CopyConstructible (C++ 2014 [copyconstructible]), CopyAssignable (C++ 2014 [copyassignable]), GettableSocketOption ([socket.reqmts.gettablesocketoption]), and SettableSocketOption ([socket.reqmts.settablesocketoption]), X is contextually convertible to bool, and X satisfies the additional requirements listed below.

In the table below, a denotes a (possibly const) value of type X, v denotes a (possibly const) value of type bool, and u denotes an identifier.

Table 29 — BooleanSocketOption requirements
expressiontypeassertion/note pre/post-conditions
X u; post: !u.value().
X u(v); post: u.value() == v.
a.value() bool Returns the current boolean value of the socket option object.
static_cast<bool>(a) bool Returns a.value().
!a bool Returns !a.value().

In this document, types that satisfy the BooleanSocketOption requirements are defined as follows.

class C{
public:
  // constructors:
  C() noexcept;
  explicit C(bool v) noexcept;

  // members:
  C& operator=(bool v) noexcept;

  bool value() const noexcept;

  explicit operator bool() const noexcept;
  bool operator!() const noexcept;
};

Extensible implementations provide the following member functions:

class C{
public:
  template<class Protocol> int level(const Protocol& p) const noexcept;
  template<class Protocol> int name(const Protocol& p) const noexcept;
  template<class Protocol> void* data(const Protocol& p) noexcept;
  template<class Protocol> const void* data(const Protocol& p) const noexcept;
  template<class Protocol> size_t size(const Protocol& p) const noexcept;
  template<class Protocol> void resize(const Protocol& p, size_t s);
  // remainder unchanged
private:
  int value_; // exposition only
};

Let L and N identify the POSIX macros to be passed as the level and option_name arguments, respectively, to POSIX setsockopt and getsockopt.

C() noexcept;

Postconditions: !value().

explicit C(bool v) noexcept;

Postconditions: value() == v.

C& operator=(bool v) noexcept;

Returns: *this.

Postconditions: value() == v.

bool value() const noexcept;

Returns: The stored socket option value. For extensible implementations, returns value_ != 0.

explicit operator bool() const noexcept;

Returns: value().

bool operator!() const noexcept;

Returns: !value().

template<class Protocol> int level(const Protocol& p) const noexcept;

Returns: L.

template<class Protocol> int name(const Protocol& p) const noexcept;

Returns: N.

template<class Protocol> void* data(const Protocol& p) noexcept;

Returns: std::addressof(value_).

template<class Protocol> const void* data(const Protocol& p) const noexcept;

Returns: std::addressof(value_).

template<class Protocol> size_t size(const Protocol& p) const noexcept;

Returns: sizeof(value_).

template<class Protocol> void resize(const Protocol& p, size_t s);

Remarks: length_error if s is not a valid data size for the protocol specified by p.

18.2.11 Integer socket options [socket.reqmts.opt.int]

A type X meets the IntegerSocketOption requirements if it satisfies the requirements of Destructible (C++ 2014 [destructible]), DefaultConstructible (C++ 2014 [defaultconstructible]), CopyConstructible (C++ 2014 [copyconstructible]), CopyAssignable (C++ 2014 [copyassignable]), GettableSocketOption ([socket.reqmts.gettablesocketoption]), and SettableSocketOption ([socket.reqmts.settablesocketoption]), as well as the additional requirements listed below.

In the table below, a denotes a (possibly const) value of type X, v denotes a (possibly const) value of type int, and u denotes an identifier.

Table 30 — IntegerSocketOption requirements
expressiontypeassertion/note pre/post-conditions
X u; post: u.value() == 0.
X u(v); post: u.value() == v.
a.value() int Returns the current integer value of the socket option object.

In this document, types that satisfy the IntegerSocketOption requirements are defined as follows.

class C{
public:
  // constructors:
  C() noexcept;
  explicit C(int v) noexcept;

  // members:
  C& operator=(int v) noexcept;

  int value() const noexcept;
};

Extensible implementations provide the following member functions:

class C{
public:
  template<class Protocol> int level(const Protocol& p) const noexcept;
  template<class Protocol> int name(const Protocol& p) const noexcept;
  template<class Protocol> void* data(const Protocol& p) noexcept;
  template<class Protocol> const void* data(const Protocol& p) const noexcept;
  template<class Protocol> size_t size(const Protocol& p) const noexcept;
  template<class Protocol> void resize(const Protocol& p, size_t s);
  // remainder unchanged
private:
  int value_; // exposition only
};

Let L and N identify the POSIX macros to be passed as the level and option_name arguments, respectively, to POSIX setsockopt and getsockopt.

C() noexcept;

Postconditions: !value().

explicit C(int v) noexcept;

Postconditions: value() == v.

C& operator=(int v) noexcept;

Returns: *this.

Postconditions: value() == v.

int value() const noexcept;

Returns: The stored socket option value. For extensible implementations, returns value_.

template<class Protocol> int level(const Protocol& p) const noexcept;

Returns: L.

template<class Protocol> int name(const Protocol& p) const noexcept;

Returns: N.

template<class Protocol> void* data(const Protocol& p) noexcept;

Returns: std::addressof(value_).

template<class Protocol> const void* data(const Protocol& p) const noexcept;

Returns: std::addressof(value_).

template<class Protocol> size_t size(const Protocol& p) const noexcept;

Returns: sizeof(value_).

template<class Protocol> void resize(const Protocol& p, size_t s);

Remarks: length_error if s is not a valid data size for the protocol specified by p.

18.2.12 I/O control command requirements [socket.reqmts.iocontrolcommand]

A type X meets the IoControlCommand requirements if it satisfies the requirements listed below.

In the table below, a denotes a (possibly const) value of type X, and b denotes a value of type X.

Table 31 — IoControlCommand requirements for extensible implementations
expressiontypeassertion/note pre/post-conditions
a.name() int Returns a value suitable for passing as the request argument to POSIX ioctl (or equivalent).
b.data() void*

18.2.13 Connect condition requirements [socket.reqmts.connectcondition]

A type X meets the ConnectCondition requirements if it satisfies the requirements of Destructible (C++ 2014 [destructible]) and CopyConstructible (C++ 2014 [copyconstructible]), as well as the additional requirements listed below.

In the table below, x denotes a value of type X, ec denotes a (possibly const) value of type error_code, and ep denotes a (possibly const) value of a type satisfying the endpoint ([socket.reqmts.endpoint]) requirements.

Table 32 — ConnectCondition requirements
expressionreturn typeassertion/note pre/post-condition
x(ec, ep) bool Returns true to indicate that the connect or async_connect algorithm should attempt a connection to the endpoint ep. Otherwise, returns false to indicate that the algorithm should not attempt connection to the endpoint ep, and should instead skip to the next endpoint in the sequence.