idfxx 1.0.0
Modern C++23 components for ESP-IDF
Loading...
Searching...
No Matches
stream_channel.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Chris Leishman
3
4#pragma once
5
17#include "sdkconfig.h"
18
19#include <idfxx/flags>
20#include <idfxx/net/endpoint>
21#include <idfxx/net/error>
22#include <idfxx/net/netconn/buffer>
24
25#include <cstddef>
26#include <cstdint>
27#include <span>
28#include <string_view>
29
30namespace idfxx::net::netconn {
31
41enum class write_flag : uint8_t {
50 no_copy = 0x01,
51 more = 0x02,
52 dont_block = 0x04,
53};
54
55} // namespace idfxx::net::netconn
56
58template<>
61
62namespace idfxx::net::netconn {
63
64class listener;
65
80class [[nodiscard]] stream_channel : public detail::base_channel {
81public:
82 // ----- construction -----
83
84#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
92#endif
93
100
101#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
111#endif
112
120
121 // ----- connect / close / shutdown -----
122
123#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
132 void connect(const endpoint& peer) { idfxx::unwrap(try_connect(peer)); }
133#endif
134
142
143#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
150 void close() { idfxx::unwrap(try_close()); }
151#endif
152
159
160#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
167 void shutdown() { idfxx::unwrap(try_shutdown()); }
168#endif
169
176
177#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
191 void shutdown(direction dir) { idfxx::unwrap(try_shutdown(dir)); }
192#endif
193
206
207 // ----- send / receive -----
208
209#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
236 size_t send(std::span<const std::byte> data, idfxx::flags<write_flag> flags = {}) {
237 return idfxx::unwrap(try_send(data, flags));
238 }
239#endif
240
258 [[nodiscard]] result<size_t> try_send(std::span<const std::byte> data, idfxx::flags<write_flag> flags = {});
259
260#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
285 size_t send(std::string_view data, idfxx::flags<write_flag> flags = {}) {
286 return idfxx::unwrap(try_send(data, flags));
287 }
288#endif
289
306
307#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
320 [[nodiscard]] buffer recv() { return idfxx::unwrap(try_recv()); }
321#endif
322
329
330#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
345 [[nodiscard]] std::span<std::byte> recv(std::span<std::byte> buf) { return idfxx::unwrap(try_recv(buf)); }
346#endif
347
356
357 // ----- endpoint -----
358
359#ifdef CONFIG_COMPILER_CXX_EXCEPTIONS
368 [[nodiscard]] endpoint peer_endpoint() const { return idfxx::unwrap(try_peer_endpoint()); }
369#endif
370
377
378private:
379 friend class listener;
380
381 stream_channel(::netconn* conn, address_family fam) noexcept
382 : base_channel(conn, fam) {}
383
384 // Once the peer closes the receive direction (ERR_CLSD), lwIP only
385 // signals that condition on the first `netconn_recv`; subsequent calls
386 // return ERR_CONN. Track the close locally so `try_recv` keeps reporting
387 // the BSD-style empty-buffer EOF instead of surfacing the stale error.
388 bool _eof = false;
389
390 // Leftover from a previous `try_recv(std::span)` whose caller buffer was
391 // smaller than the segment lwIP delivered. The netbuf-returning
392 // `try_recv` has no partial-consume hook on the lwIP side, so when the
393 // copy overshoots we keep the netbuf alive here and drain the remainder
394 // on subsequent span-recv calls. Cleared on close/shutdown and moved
395 // along with the channel.
396 buffer _pending;
397 size_t _pending_offset = 0;
398};
399
400} // namespace idfxx::net::netconn
401
// end of idfxx_net_netconn_stream_channel
Type-safe set of flags from a scoped enum.
Definition flags.hpp:88
Address/port pair identifying a transport endpoint.
Definition endpoint.hpp:129
Owning handle for a netconn buffer.
Definition buffer.hpp:60
A TCP listening netconn.
Definition listener.hpp:43
result< void > try_close()
Closes the netconn.
size_t send(std::span< const std::byte > data, idfxx::flags< write_flag > flags={})
Sends a buffer on the TCP netconn.
void shutdown(direction dir)
Shuts down one direction on the netconn (half-close).
buffer recv()
Receives the next buffer from the connection.
stream_channel(address_family fam)
Creates a TCP netconn for the given address family.
result< void > try_shutdown()
Shuts down both directions on the netconn.
result< endpoint > try_peer_endpoint() const
Returns the remote endpoint the channel is connected to.
result< buffer > try_recv()
Receives the next buffer from the connection.
std::span< std::byte > recv(std::span< std::byte > buf)
Receives data into a caller-provided buffer.
result< void > try_connect(const endpoint &peer)
Connects to the given remote endpoint.
result< std::span< std::byte > > try_recv(std::span< std::byte > buf)
Receives data into a caller-provided buffer.
result< void > try_shutdown(direction dir)
Shuts down one direction on the netconn (half-close).
static result< stream_channel > make()
Creates a TCP netconn with default address family (IPv4).
void shutdown()
Shuts down both directions on the netconn.
size_t send(std::string_view data, idfxx::flags< write_flag > flags={})
Sends a string view on the TCP netconn.
static result< stream_channel > make(address_family fam)
Creates a TCP netconn for the given address family.
void connect(const endpoint &peer)
Connects to the given remote endpoint.
result< size_t > try_send(std::string_view data, idfxx::flags< write_flag > flags={})
Sends a string view on the TCP netconn.
endpoint peer_endpoint() const
Returns the remote endpoint the channel is connected to.
stream_channel()
Creates a TCP netconn with default address family (IPv4).
result< size_t > try_send(std::span< const std::byte > data, idfxx::flags< write_flag > flags={})
Sends a buffer on the TCP netconn.
write_flag
Flags accepted by stream_channel::send / try_send.
@ dont_block
Return immediately rather than waiting for buffer space.
@ no_copy
Zero-copy: reference the caller's buffer rather than copying it.
@ more
Suppress the TCP PSH flag (allow more data to be coalesced).
address_family
Address family.
Definition endpoint.hpp:37
direction
One direction of a bidirectional transport.
Definition endpoint.hpp:70
T unwrap(result< T > result)
Throws a std::system_error if the result is an error.
Definition error.hpp:307
std::expected< T, std::error_code > result
result type wrapping a value or error code.
Definition error.hpp:120