Add basic send_to/recv_from functionality to socket class. · SpaceView/cppcoro@16e0df5 · GitHub
Skip to content

Commit 16e0df5

Browse files
committed
Add basic send_to/recv_from functionality to socket class.
1 parent be0c017 commit 16e0df5

8 files changed

Lines changed: 534 additions & 1 deletion

include/cppcoro/net/socket.hpp

Lines changed: 24 additions & 0 deletions
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
///////////////////////////////////////////////////////////////////////////////
2+
// Copyright (c) Lewis Baker
3+
// Licenced under MIT license. See LICENSE.txt for details.
4+
///////////////////////////////////////////////////////////////////////////////
5+
#ifndef CPPCORO_NET_SOCKET_RECV_FROM_OPERATION_HPP_INCLUDED
6+
#define CPPCORO_NET_SOCKET_RECV_FROM_OPERATION_HPP_INCLUDED
7+
8+
#include <cppcoro/config.hpp>
9+
#include <cppcoro/cancellation_token.hpp>
10+
#include <cppcoro/net/ip_endpoint.hpp>
11+
12+
#include <cstdint>
13+
#include <tuple>
14+
15+
#if CPPCORO_OS_WINNT
16+
# include <cppcoro/detail/win32.hpp>
17+
# include <cppcoro/detail/win32_overlapped_operation.hpp>
18+
19+
namespace cppcoro::net
20+
{
21+
class socket;
22+
23+
class socket_recv_from_operation_impl
24+
{
25+
public:
26+
27+
socket_recv_from_operation_impl(
28+
socket& socket,
29+
void* buffer,
30+
std::size_t byteCount) noexcept
31+
: m_socket(socket)
32+
, m_buffer(buffer, byteCount)
33+
{}
34+
35+
bool try_start(cppcoro::detail::win32_overlapped_operation_base& operation) noexcept;
36+
void cancel(cppcoro::detail::win32_overlapped_operation_base& operation) noexcept;
37+
std::tuple<std::size_t, ip_endpoint> get_result(
38+
cppcoro::detail::win32_overlapped_operation_base& operation);
39+
40+
private:
41+
42+
socket& m_socket;
43+
cppcoro::detail::win32::wsabuf m_buffer;
44+
45+
static constexpr std::size_t sockaddrStorageAlignment = 4;
46+
47+
// Storage suitable for either SOCKADDR_IN or SOCKADDR_IN6
48+
alignas(sockaddrStorageAlignment) std::uint8_t m_sourceSockaddrStorage[28];
49+
int m_sourceSockaddrLength;
50+
51+
};
52+
53+
class socket_recv_from_operation
54+
: public cppcoro::detail::win32_overlapped_operation<socket_recv_from_operation>
55+
{
56+
public:
57+
58+
socket_recv_from_operation(
59+
socket& socket,
60+
void* buffer,
61+
std::size_t byteCount) noexcept
62+
: m_impl(socket, buffer, byteCount)
63+
{}
64+
65+
private:
66+
67+
friend class cppcoro::detail::win32_overlapped_operation<socket_recv_from_operation>;
68+
69+
bool try_start() noexcept { return m_impl.try_start(*this); }
70+
decltype(auto) get_result() { return m_impl.get_result(*this); }
71+
72+
socket_recv_from_operation_impl m_impl;
73+
74+
};
75+
76+
class socket_recv_from_operation_cancellable
77+
: public cppcoro::detail::win32_overlapped_operation_cancellable<socket_recv_from_operation_cancellable>
78+
{
79+
public:
80+
81+
socket_recv_from_operation_cancellable(
82+
socket& socket,
83+
void* buffer,
84+
std::size_t byteCount,
85+
cancellation_token&& ct) noexcept
86+
: cppcoro::detail::win32_overlapped_operation_cancellable<socket_recv_from_operation_cancellable>(std::move(ct))
87+
, m_impl(socket, buffer, byteCount)
88+
{}
89+
90+
private:
91+
92+
friend class cppcoro::detail::win32_overlapped_operation_cancellable<socket_recv_from_operation_cancellable>;
93+
94+
bool try_start() noexcept { return m_impl.try_start(*this); }
95+
void cancel() noexcept { m_impl.cancel(*this); }
96+
decltype(auto) get_result() { return m_impl.get_result(*this); }
97+
98+
socket_recv_from_operation_impl m_impl;
99+
100+
};
101+
102+
}
103+
104+
#endif // CPPCORO_OS_WINNT
105+
106+
#endif
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
///////////////////////////////////////////////////////////////////////////////
2+
// Copyright (c) Lewis Baker
3+
// Licenced under MIT license. See LICENSE.txt for details.
4+
///////////////////////////////////////////////////////////////////////////////
5+
#ifndef CPPCORO_NET_SOCKET_SEND_TO_OPERATION_HPP_INCLUDED
6+
#define CPPCORO_NET_SOCKET_SEND_TO_OPERATION_HPP_INCLUDED
7+
8+
#include <cppcoro/config.hpp>
9+
#include <cppcoro/cancellation_token.hpp>
10+
#include <cppcoro/net/ip_endpoint.hpp>
11+
12+
#include <cstdint>
13+
14+
#if CPPCORO_OS_WINNT
15+
# include <cppcoro/detail/win32.hpp>
16+
# include <cppcoro/detail/win32_overlapped_operation.hpp>
17+
18+
namespace cppcoro::net
19+
{
20+
class socket;
21+
22+
class socket_send_to_operation_impl
23+
{
24+
public:
25+
26+
socket_send_to_operation_impl(
27+
socket& s,
28+
const ip_endpoint& destination,
29+
const void* buffer,
30+
std::size_t byteCount) noexcept
31+
: m_socket(s)
32+
, m_destination(destination)
33+
, m_buffer(const_cast<void*>(buffer), byteCount)
34+
{}
35+
36+
bool try_start(cppcoro::detail::win32_overlapped_operation_base& operation) noexcept;
37+
void cancel(cppcoro::detail::win32_overlapped_operation_base& operation) noexcept;
38+
39+
private:
40+
41+
socket& m_socket;
42+
ip_endpoint m_destination;
43+
cppcoro::detail::win32::wsabuf m_buffer;
44+
45+
};
46+
47+
class socket_send_to_operation
48+
: public cppcoro::detail::win32_overlapped_operation<socket_send_to_operation>
49+
{
50+
public:
51+
52+
socket_send_to_operation(
53+
socket& s,
54+
const ip_endpoint& destination,
55+
const void* buffer,
56+
std::size_t byteCount) noexcept
57+
: m_impl(s, destination, buffer, byteCount)
58+
{}
59+
60+
private:
61+
62+
friend class cppcoro::detail::win32_overlapped_operation<socket_send_to_operation>;
63+
64+
bool try_start() noexcept { return m_impl.try_start(*this); }
65+
66+
socket_send_to_operation_impl m_impl;
67+
68+
};
69+
70+
class socket_send_to_operation_cancellable
71+
: public cppcoro::detail::win32_overlapped_operation_cancellable<socket_send_to_operation_cancellable>
72+
{
73+
public:
74+
75+
socket_send_to_operation_cancellable(
76+
socket& s,
77+
const ip_endpoint& destination,
78+
const void* buffer,
79+
std::size_t byteCount,
80+
cancellation_token&& ct) noexcept
81+
: cppcoro::detail::win32_overlapped_operation_cancellable<socket_send_to_operation_cancellable>(std::move(ct))
82+
, m_impl(s, destination, buffer, byteCount)
83+
{}
84+
85+
private:
86+
87+
friend class cppcoro::detail::win32_overlapped_operation_cancellable<socket_send_to_operation_cancellable>;
88+
89+
bool try_start() noexcept { return m_impl.try_start(*this); }
90+
void cancel() noexcept { return m_impl.cancel(*this); }
91+
92+
socket_send_to_operation_impl m_impl;
93+
94+
};
95+
96+
}
97+
98+
#endif // CPPCORO_OS_WINNT
99+
100+
#endif

lib/build.cake

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,10 @@ if variant.platform == "windows":
101101
'socket_accept_operation.hpp',
102102
'socket_connect_operation.hpp',
103103
'socket_disconnect_operation.hpp',
104-
'socket_send_operation.hpp',
105104
'socket_recv_operation.hpp',
105+
'socket_recv_from_operation.hpp',
106+
'socket_send_operation.hpp',
107+
'socket_send_to_operation.hpp',
106108
]))
107109
sources.extend(script.cwd([
108110
'win32.cpp',
@@ -121,7 +123,9 @@ if variant.platform == "windows":
121123
'socket_connect_operation.cpp',
122124
'socket_disconnect_operation.cpp',
123125
'socket_send_operation.cpp',
126+
'socket_send_to_operation.cpp',
124127
'socket_recv_operation.cpp',
128+
'socket_recv_from_operation.cpp',
125129
]))
126130

127131
buildDir = env.expand('${CPPCORO_BUILD}')

lib/socket.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,30 @@ cppcoro::net::socket::recv(void* buffer, std::size_t byteCount, cancellation_tok
432432
return socket_recv_operation_cancellable{ *this, buffer, byteCount, std::move(ct) };
433433
}
434434

435+
cppcoro::net::socket_recv_from_operation
436+
cppcoro::net::socket::recv_from(void* buffer, std::size_t byteCount) noexcept
437+
{
438+
return socket_recv_from_operation{ *this, buffer, byteCount };
439+
}
440+
441+
cppcoro::net::socket_recv_from_operation_cancellable
442+
cppcoro::net::socket::recv_from(void* buffer, std::size_t byteCount, cancellation_token ct) noexcept
443+
{
444+
return socket_recv_from_operation_cancellable{ *this, buffer, byteCount, std::move(ct) };
445+
}
446+
447+
cppcoro::net::socket_send_to_operation
448+
cppcoro::net::socket::send_to(const ip_endpoint& destination, const void* buffer, std::size_t byteCount) noexcept
449+
{
450+
return socket_send_to_operation{ *this, destination, buffer, byteCount };
451+
}
452+
453+
cppcoro::net::socket_send_to_operation_cancellable
454+
cppcoro::net::socket::send_to(const ip_endpoint& destination, const void* buffer, std::size_t byteCount, cancellation_token ct) noexcept
455+
{
456+
return socket_send_to_operation_cancellable{ *this, destination, buffer, byteCount, std::move(ct) };
457+
}
458+
435459
void cppcoro::net::socket::close_send()
436460
{
437461
int result = ::shutdown(m_handle, SD_SEND);

lib/socket_recv_from_operation.cpp

Lines changed: 96 additions & 0 deletions

0 commit comments

Comments
 (0)