@@ -30,7 +30,7 @@ class client
30
30
};
31
31
32
32
/* *
33
- * Creates a new tcp client that can connect to an ip address + port. By default the socket
33
+ * Creates a new tcp client that can connect to an ip address + port. By default, the socket
34
34
* created will be in non-blocking mode, meaning that any sending or receiving of data should
35
35
* poll for event readiness prior.
36
36
* @param scheduler The io scheduler to drive the tcp client.
@@ -43,7 +43,7 @@ class client
43
43
.port = 8080 ,
44
44
});
45
45
client (const client& other);
46
- client (client&& other);
46
+ client (client&& other) noexcept ;
47
47
auto operator =(const client& other) noexcept -> client&;
48
48
auto operator =(client&& other) noexcept -> client&;
49
49
~client ();
@@ -52,8 +52,8 @@ class client
52
52
* @return The tcp socket this client is using.
53
53
* @{
54
54
**/
55
- auto socket () -> net::socket& { return m_socket; }
56
- auto socket () const -> const net::socket& { return m_socket; }
55
+ [[nodiscard]] auto socket () -> net::socket& { return m_socket; }
56
+ [[nodiscard]] auto socket () const -> const net::socket& { return m_socket; }
57
57
/* * @} */
58
58
59
59
/* *
@@ -66,81 +66,78 @@ class client
66
66
67
67
/* *
68
68
* Polls for the given operation on this client's tcp socket. This should be done prior to
69
- * calling recv and after a send that doesn't send the entire buffer.
69
+ * calling recv and after a send call that doesn't send the entire buffer.
70
70
* @param op The poll operation to perform, use read for incoming data and write for outgoing.
71
71
* @param timeout The amount of time to wait for the poll event to be ready. Use zero for infinte timeout.
72
72
* @return The status result of th poll operation. When poll_status::event is returned then the
73
73
* event operation is ready.
74
74
*/
75
- auto poll (coro::poll_op op, std::chrono::milliseconds timeout = std::chrono::milliseconds{0 })
75
+ auto poll (const coro::poll_op op, const std::chrono::milliseconds timeout = std::chrono::milliseconds{0 })
76
76
-> coro::task<poll_status>
77
77
{
78
78
return m_io_scheduler->poll (m_socket, op, timeout);
79
79
}
80
80
81
81
/* *
82
- * Receives incoming data into the given buffer. By default since all tcp client sockets are set
82
+ * Receives incoming data into the given buffer. By default, since all tcp client sockets are set
83
83
* to non-blocking use co_await poll() to determine when data is ready to be received.
84
84
* @param buffer Received bytes are written into this buffer up to the buffers size.
85
- * @return The status of the recv call and a span of the bytes recevied (if any). The span of
85
+ * @return The status of the recv call and a span of the bytes received (if any). The span of
86
86
* bytes will be a subspan or full span of the given input buffer.
87
87
*/
88
- template <concepts::mutable_buffer buffer_type>
89
- auto recv (buffer_type&& buffer) -> std::pair<recv_status, std::span<char >>
88
+ template <concepts::mutable_buffer buffer_type, typename element_type = typename concepts::mutable_buffer_traits<buffer_type>::element_type >
89
+ auto recv (buffer_type&& buffer) -> std::pair<recv_status, std::span<element_type >>
90
90
{
91
91
// If the user requested zero bytes, just return.
92
92
if (buffer.empty ())
93
93
{
94
- return {recv_status::ok, std::span<char >{}};
94
+ return {recv_status::ok, std::span<element_type >{}};
95
95
}
96
96
97
97
auto bytes_recv = ::recv (m_socket.native_handle (), buffer.data (), buffer.size (), 0 );
98
98
if (bytes_recv > 0 )
99
99
{
100
- // Ok, we've recieved some data.
101
- return {recv_status::ok, std::span<char >{buffer.data (), static_cast <size_t >(bytes_recv)}};
100
+ // Ok, we've received some data.
101
+ return {recv_status::ok, std::span<element_type >{buffer.data (), static_cast <size_t >(bytes_recv)}};
102
102
}
103
- else if (bytes_recv == 0 )
103
+
104
+ if (bytes_recv == 0 )
104
105
{
105
106
// On TCP stream sockets 0 indicates the connection has been closed by the peer.
106
- return {recv_status::closed, std::span<char >{}};
107
- }
108
- else
109
- {
110
- // Report the error to the user.
111
- return {static_cast <recv_status>(errno), std::span<char >{}};
107
+ return {recv_status::closed, std::span<element_type>{}};
112
108
}
109
+
110
+ // Report the error to the user.
111
+ return {static_cast <recv_status>(errno), std::span<element_type>{}};
113
112
}
114
113
115
114
/* *
116
- * Sends outgoing data from the given buffer. If a partial write occurs then use co_await poll()
115
+ * Sends outgoing data from the given buffer. If a partial write occurs then use co_await poll()
117
116
* to determine when the tcp client socket is ready to be written to again. On partial writes
118
117
* the status will be 'ok' and the span returned will be non-empty, it will contain the buffer
119
118
* span data that was not written to the client's socket.
120
119
* @param buffer The data to write on the tcp socket.
121
120
* @return The status of the send call and a span of any remaining bytes not sent. If all bytes
122
121
* were successfully sent the status will be 'ok' and the remaining span will be empty.
123
122
*/
124
- template <concepts::const_buffer buffer_type>
125
- auto send (const buffer_type& buffer) -> std::pair<send_status, std::span<const char >>
123
+ template <concepts::const_buffer buffer_type, typename element_type = typename concepts::const_buffer_traits<buffer_type>::element_type >
124
+ auto send (const buffer_type& buffer) -> std::pair<send_status, std::span<element_type >>
126
125
{
127
126
// If the user requested zero bytes, just return.
128
127
if (buffer.empty ())
129
128
{
130
- return {send_status::ok, std::span<const char >{buffer.data (), buffer.size ()}};
129
+ return {send_status::ok, std::span<element_type >{buffer.data (), buffer.size ()}};
131
130
}
132
131
133
132
auto bytes_sent = ::send (m_socket.native_handle (), buffer.data (), buffer.size (), 0 );
134
133
if (bytes_sent >= 0 )
135
134
{
136
135
// Some or all of the bytes were written.
137
- return {send_status::ok, std::span<const char >{buffer.data () + bytes_sent, buffer.size () - bytes_sent}};
138
- }
139
- else
140
- {
141
- // Due to the error none of the bytes were written.
142
- return {static_cast <send_status>(errno), std::span<const char >{buffer.data (), buffer.size ()}};
136
+ return {send_status::ok, std::span<element_type>{buffer.data () + bytes_sent, buffer.size () - bytes_sent}};
143
137
}
138
+
139
+ // Due to the error none of the bytes were written.
140
+ return {static_cast <send_status>(errno), std::span<element_type>{buffer.data (), buffer.size ()}};
144
141
}
145
142
146
143
private:
@@ -154,7 +151,7 @@ class client
154
151
options m_options{};
155
152
// / The tcp socket.
156
153
net::socket m_socket{-1 };
157
- // / Cache the status of the connect in the event the user calls connect() again.
154
+ // / Cache the status of the connect call in the event the user calls connect() again.
158
155
std::optional<net::connect_status> m_connect_status{std::nullopt };
159
156
};
160
157
0 commit comments