|
||||
File indexing completed on 2025-01-30 10:03:46
0001 /////////////////////////////////////////////////////////////////////////////// 0002 // Copyright (c) Lewis Baker 0003 // Licenced under MIT license. See LICENSE.txt for details. 0004 /////////////////////////////////////////////////////////////////////////////// 0005 #ifndef CPPCORO_NET_SOCKET_HPP_INCLUDED 0006 #define CPPCORO_NET_SOCKET_HPP_INCLUDED 0007 0008 #include <cppcoro/config.hpp> 0009 0010 #include <cppcoro/net/ip_endpoint.hpp> 0011 #include <cppcoro/net/socket_accept_operation.hpp> 0012 #include <cppcoro/net/socket_connect_operation.hpp> 0013 #include <cppcoro/net/socket_disconnect_operation.hpp> 0014 #include <cppcoro/net/socket_recv_operation.hpp> 0015 #include <cppcoro/net/socket_recv_from_operation.hpp> 0016 #include <cppcoro/net/socket_send_operation.hpp> 0017 #include <cppcoro/net/socket_send_to_operation.hpp> 0018 0019 #include <cppcoro/cancellation_token.hpp> 0020 0021 #if CPPCORO_OS_WINNT 0022 # include <cppcoro/detail/win32.hpp> 0023 #endif 0024 0025 namespace cppcoro 0026 { 0027 class io_service; 0028 0029 namespace net 0030 { 0031 class socket 0032 { 0033 public: 0034 0035 /// Create a socket that can be used to communicate using TCP/IPv4 protocol. 0036 /// 0037 /// \param ioSvc 0038 /// The I/O service the socket will use for dispatching I/O completion events. 0039 /// 0040 /// \return 0041 /// The newly created socket. 0042 /// 0043 /// \throws std::system_error 0044 /// If the socket could not be created for some reason. 0045 static socket create_tcpv4(io_service& ioSvc); 0046 0047 /// Create a socket that can be used to communicate using TCP/IPv6 protocol. 0048 /// 0049 /// \param ioSvc 0050 /// The I/O service the socket will use for dispatching I/O completion events. 0051 /// 0052 /// \return 0053 /// The newly created socket. 0054 /// 0055 /// \throws std::system_error 0056 /// If the socket could not be created for some reason. 0057 static socket create_tcpv6(io_service& ioSvc); 0058 0059 /// Create a socket that can be used to communicate using UDP/IPv4 protocol. 0060 /// 0061 /// \param ioSvc 0062 /// The I/O service the socket will use for dispatching I/O completion events. 0063 /// 0064 /// \return 0065 /// The newly created socket. 0066 /// 0067 /// \throws std::system_error 0068 /// If the socket could not be created for some reason. 0069 static socket create_udpv4(io_service& ioSvc); 0070 0071 /// Create a socket that can be used to communicate using UDP/IPv6 protocol. 0072 /// 0073 /// \param ioSvc 0074 /// The I/O service the socket will use for dispatching I/O completion events. 0075 /// 0076 /// \return 0077 /// The newly created socket. 0078 /// 0079 /// \throws std::system_error 0080 /// If the socket could not be created for some reason. 0081 static socket create_udpv6(io_service& ioSvc); 0082 0083 socket(socket&& other) noexcept; 0084 0085 /// Closes the socket, releasing any associated resources. 0086 /// 0087 /// If the socket still has an open connection then the connection will be 0088 /// reset. The destructor will not block waiting for queueud data to be sent. 0089 /// If you need to ensure that queued data is delivered then you must call 0090 /// disconnect() and wait until the disconnect operation completes. 0091 ~socket(); 0092 0093 socket& operator=(socket&& other) noexcept; 0094 0095 #if CPPCORO_OS_WINNT 0096 /// Get the Win32 socket handle assocaited with this socket. 0097 cppcoro::detail::win32::socket_t native_handle() noexcept { return m_handle; } 0098 0099 /// Query whether I/O operations that complete synchronously will skip posting 0100 /// an I/O completion event to the I/O completion port. 0101 /// 0102 /// The operation class implementations can use this to determine whether or not 0103 /// it should immediately resume the coroutine on the current thread upon an 0104 /// operation completing synchronously or whether it should suspend the coroutine 0105 /// and wait until the I/O completion event is dispatched to an I/O thread. 0106 bool skip_completion_on_success() noexcept { return m_skipCompletionOnSuccess; } 0107 #endif 0108 0109 /// Get the address and port of the local end-point. 0110 /// 0111 /// If the socket is not bound then this will be the unspecified end-point 0112 /// of the socket's associated address-family. 0113 const ip_endpoint& local_endpoint() const noexcept { return m_localEndPoint; } 0114 0115 /// Get the address and port of the remote end-point. 0116 /// 0117 /// If the socket is not in the connected state then this will be the unspecified 0118 /// end-point of the socket's associated address-family. 0119 const ip_endpoint& remote_endpoint() const noexcept { return m_remoteEndPoint; } 0120 0121 /// Bind the local end of this socket to the specified local end-point. 0122 /// 0123 /// \param localEndPoint 0124 /// The end-point to bind to. 0125 /// This can be either an unspecified address (in which case it binds to all available 0126 /// interfaces) and/or an unspecified port (in which case a random port is allocated). 0127 /// 0128 /// \throws std::system_error 0129 /// If the socket could not be bound for some reason. 0130 void bind(const ip_endpoint& localEndPoint); 0131 0132 /// Put the socket into a passive listening state that will start acknowledging 0133 /// and queueing up new connections ready to be accepted by a call to 'accept()'. 0134 /// 0135 /// The backlog of connections ready to be accepted will be set to some default 0136 /// suitable large value, depending on the network provider. If you need more 0137 /// control over the size of the queue then use the overload of listen() 0138 /// that accepts a 'backlog' parameter. 0139 /// 0140 /// \throws std::system_error 0141 /// If the socket could not be placed into a listening mode. 0142 void listen(); 0143 0144 /// Put the socket into a passive listening state that will start acknowledging 0145 /// and queueing up new connections ready to be accepted by a call to 'accept()'. 0146 /// 0147 /// \param backlog 0148 /// The maximum number of pending connections to allow in the queue of ready-to-accept 0149 /// connections. 0150 /// 0151 /// \throws std::system_error 0152 /// If the socket could not be placed into a listening mode. 0153 void listen(std::uint32_t backlog); 0154 0155 /// Connect the socket to the specified remote end-point. 0156 /// 0157 /// The socket must be in a bound but unconnected state prior to this call. 0158 /// 0159 /// \param remoteEndPoint 0160 /// The IP address and port-number to connect to. 0161 /// 0162 /// \return 0163 /// An awaitable object that must be co_await'ed to perform the async connect 0164 /// operation. The result of the co_await expression is type void. 0165 [[nodiscard]] 0166 socket_connect_operation connect(const ip_endpoint& remoteEndPoint) noexcept; 0167 0168 /// Connect to the specified remote end-point. 0169 /// 0170 /// \param remoteEndPoint 0171 /// The IP address and port of the remote end-point to connect to. 0172 /// 0173 /// \param ct 0174 /// A cancellation token that can be used to communicate a request to 0175 /// later cancel the operation. If the operation is successfully 0176 /// cancelled then it will complete by throwing a cppcoro::operation_cancelled 0177 /// exception. 0178 /// 0179 /// \return 0180 /// An awaitable object that will start the connect operation when co_await'ed 0181 /// and will suspend the coroutine, resuming it when the operation completes. 0182 /// The result of the co_await expression has type 'void'. 0183 [[nodiscard]] 0184 socket_connect_operation_cancellable connect( 0185 const ip_endpoint& remoteEndPoint, 0186 cancellation_token ct) noexcept; 0187 0188 [[nodiscard]] 0189 socket_accept_operation accept(socket& acceptingSocket) noexcept; 0190 [[nodiscard]] 0191 socket_accept_operation_cancellable accept( 0192 socket& acceptingSocket, 0193 cancellation_token ct) noexcept; 0194 0195 [[nodiscard]] 0196 socket_disconnect_operation disconnect() noexcept; 0197 [[nodiscard]] 0198 socket_disconnect_operation_cancellable disconnect(cancellation_token ct) noexcept; 0199 0200 [[nodiscard]] 0201 socket_send_operation send( 0202 const void* buffer, 0203 std::size_t size) noexcept; 0204 [[nodiscard]] 0205 socket_send_operation_cancellable send( 0206 const void* buffer, 0207 std::size_t size, 0208 cancellation_token ct) noexcept; 0209 0210 [[nodiscard]] 0211 socket_recv_operation recv( 0212 void* buffer, 0213 std::size_t size) noexcept; 0214 [[nodiscard]] 0215 socket_recv_operation_cancellable recv( 0216 void* buffer, 0217 std::size_t size, 0218 cancellation_token ct) noexcept; 0219 0220 [[nodiscard]] 0221 socket_recv_from_operation recv_from( 0222 void* buffer, 0223 std::size_t size) noexcept; 0224 [[nodiscard]] 0225 socket_recv_from_operation_cancellable recv_from( 0226 void* buffer, 0227 std::size_t size, 0228 cancellation_token ct) noexcept; 0229 0230 [[nodiscard]] 0231 socket_send_to_operation send_to( 0232 const ip_endpoint& destination, 0233 const void* buffer, 0234 std::size_t size) noexcept; 0235 [[nodiscard]] 0236 socket_send_to_operation_cancellable send_to( 0237 const ip_endpoint& destination, 0238 const void* buffer, 0239 std::size_t size, 0240 cancellation_token ct) noexcept; 0241 0242 void close_send(); 0243 void close_recv(); 0244 0245 private: 0246 0247 friend class socket_accept_operation_impl; 0248 friend class socket_connect_operation_impl; 0249 0250 #if CPPCORO_OS_WINNT 0251 explicit socket( 0252 cppcoro::detail::win32::socket_t handle, 0253 bool skipCompletionOnSuccess) noexcept; 0254 #endif 0255 0256 #if CPPCORO_OS_WINNT 0257 cppcoro::detail::win32::socket_t m_handle; 0258 bool m_skipCompletionOnSuccess; 0259 #endif 0260 0261 ip_endpoint m_localEndPoint; 0262 ip_endpoint m_remoteEndPoint; 0263 0264 }; 0265 } 0266 } 0267 0268 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |