userver: userver/engine/io/socket.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
socket.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/io/socket.hpp
4/// @brief @copybrief engine::io::Socket
5
6#include <sys/socket.h>
7
8#include <initializer_list>
9
10#include <userver/engine/deadline.hpp>
11#include <userver/engine/io/common.hpp>
12#include <userver/engine/io/exception.hpp>
13#include <userver/engine/io/fd_control_holder.hpp>
14#include <userver/engine/io/sockaddr.hpp>
15
16struct iovec;
17
18USERVER_NAMESPACE_BEGIN
19
20namespace engine::io {
21
22/// Socket type
23enum class SocketType {
24 kStream = SOCK_STREAM, ///< Stream socket (e.g. TCP)
25 kDgram = SOCK_DGRAM, ///< Datagram socket (e.g. UDP)
26
27 kTcp = kStream,
28 kUdp = kDgram,
29};
30
31/// @brief Socket representation.
32///
33/// It is not thread-safe to concurrently read from socket. It is not
34/// thread-safe to concurrently write to socket. However it is safe to
35/// concurrently read and write into socket:
36/// @snippet src/engine/io/socket_test.cpp send self concurrent
37class [[nodiscard]] Socket final : public RwBase {
38 public:
40 size_t bytes_received{0};
41 Sockaddr src_addr;
42 };
43
44 /// Constructs an invalid socket.
45 Socket() = default;
46
47 /// Constructs a socket for the address domain of specified type.
49
50 /// @brief Adopts an existing socket for specified address domain.
51 /// @note File descriptor will be silently forced to nonblocking mode.
52 explicit Socket(int fd, AddrDomain domain = AddrDomain::kUnspecified);
53
54 /// Whether the socket is valid.
55 explicit operator bool() const { return IsValid(); }
56
57 /// Whether the socket is valid.
58 bool IsValid() const override;
59
60 /// @brief Connects the socket to a specified endpoint.
61 /// @note Sockaddr domain must match the socket's domain.
62 void Connect(const Sockaddr&, Deadline);
63
64 /// @brief Binds the socket to the specified endpoint.
65 /// @note Sockaddr domain must match the socket's domain.
66 void Bind(const Sockaddr&);
67
68 /// Starts listening for connections on a specified socket (must be bound).
69 void Listen(int backlog = SOMAXCONN);
70
71 /// Suspends current task until the socket has data available.
72 [[nodiscard]] bool WaitReadable(Deadline) override;
73
74 /// Suspends current task until the socket can accept more data.
75 [[nodiscard]] bool WaitWriteable(Deadline) override;
76
77 /// @brief Receives at least one byte from the socket.
78 /// @returns 0 if connection is closed on one side and no data could be
79 /// received any more, received bytes count otherwise.
80 [[nodiscard]] size_t RecvSome(void* buf, size_t len, Deadline deadline);
81
82 /// @brief Receives exactly len bytes from the socket.
83 /// @note Can return less than len if socket is closed by peer.
84 [[nodiscard]] size_t RecvAll(void* buf, size_t len, Deadline deadline);
85
86 /// @brief Sends a buffer vector to the socket.
87 /// @note Can return less than len if socket is closed by peer.
88 /// @snippet src/engine/io/socket_test.cpp send vector data in socket
91
92 [[nodiscard]] size_t WriteAll(std::initializer_list<IoData> list,
93 Deadline deadline) override {
94 return SendAll(list, deadline);
95 }
96
97 /// @brief Sends exactly list_size IoData to the socket.
98 /// @note Can return less than len if socket is closed by peer.
99 [[nodiscard]] size_t SendAll(const IoData* list, std::size_t list_size,
101
102 /// @brief Sends exactly list_size iovec to the socket.
103 /// @note Can return less than len if socket is closed by peer.
104 [[nodiscard]] size_t SendAll(const struct iovec* list, std::size_t list_size,
106
107 /// @brief Sends exactly len bytes to the socket.
108 /// @note Can return less than len if socket is closed by peer.
109 [[nodiscard]] size_t SendAll(const void* buf, size_t len, Deadline deadline);
110
111 /// @brief Accepts a connection from a listening socket.
112 /// @see engine::io::Listen
113 [[nodiscard]] Socket Accept(Deadline);
114
115 /// @brief Receives at least one byte from the socket, returning source
116 /// address.
117 /// @returns 0 in bytes_sent if connection is closed on one side and no data
118 /// could be received any more, received bytes count otherwise + source
119 /// address.
120 [[nodiscard]] RecvFromResult RecvSomeFrom(void* buf, size_t len,
121 Deadline deadline);
122
123 /// @brief Sends exactly len bytes to the specified address via the socket.
124 /// @note Can return less than len in bytes_sent if socket is closed by peer.
125 /// @note Sockaddr domain must match the socket's domain.
126 /// @note Not for SocketType::kStream connections, see `man sendto`.
127 [[nodiscard]] size_t SendAllTo(const Sockaddr& dest_addr, const void* buf,
129
130 /// File descriptor corresponding to this socket.
131 int Fd() const;
132
133 /// Address of a remote peer.
134 const Sockaddr& Getpeername();
135
136 /// Local socket address.
137 const Sockaddr& Getsockname();
138
139 /// Releases file descriptor and invalidates the socket.
140 [[nodiscard]] int Release() && noexcept;
141
142 /// @brief Closes and invalidates the socket.
143 /// @warning You should not call Close with pending I/O. This may work okay
144 /// sometimes but it's loosely predictable.
145 void Close();
146
147 /// Retrieves a socket option.
148 int GetOption(int layer, int optname) const;
149
150 /// Sets a socket option.
151 void SetOption(int layer, int optname, int optval);
152
153 /// @brief Receives at least one byte from the socket.
154 /// @returns 0 if connection is closed on one side and no data could be
155 /// received any more, received bytes count otherwise.
156 [[nodiscard]] size_t ReadSome(void* buf, size_t len,
157 Deadline deadline) override {
158 return RecvSome(buf, len, deadline);
159 }
160
161 /// @brief Receives exactly len bytes from the socket.
162 /// @note Can return less than len if socket is closed by peer.
163 [[nodiscard]] size_t ReadAll(void* buf, size_t len,
164 Deadline deadline) override {
165 return RecvAll(buf, len, deadline);
166 }
167
168 /// @brief Writes exactly len bytes to the socket.
169 /// @note Can return less than len if socket is closed by peer.
170 [[nodiscard]] size_t WriteAll(const void* buf, size_t len,
171 Deadline deadline) override {
172 return SendAll(buf, len, deadline);
173 }
174
175 private:
177
178 impl::FdControlHolder fd_control_;
179 Sockaddr peername_;
180 Sockaddr sockname_;
181};
182
183} // namespace engine::io
184
185USERVER_NAMESPACE_END