25#ifndef JOIN_CORE_STREAM_SOCKET_HPP
26#define JOIN_CORE_STREAM_SOCKET_HPP
35#include <sys/socket.h>
42 template <
class Protocol>
46 template <
class P,
class E,
size_t N>
50 using Ptr = std::unique_ptr<BasicStreamSocket<Protocol>>;
84 this->
_state = State::Connected;
88 if (this->
protocol () == IPPROTO_TCP)
113 ,
_remote (std::move (other._remote))
126 _remote = std::move (other._remote);
143 if ((this->
_state != State::Closed) && (this->
_state != State::Disconnected))
149 if ((this->
_state == State::Closed) && (this->
open (endpoint.protocol ()) == -1))
154 int result =
::connect (this->
_handle, endpoint.addr (), endpoint.length ());
156 this->
_state = State::Connecting;
161 lastError = std::error_code (errno, std::generic_category ());
162 if (lastError != std::errc::operation_in_progress)
169 this->
_state = State::Connected;
190 return waitConnected (std::chrono::steady_clock::now () + timeout);
200 if (this->
_state != State::Connected)
202 if (this->
_state != State::Connecting)
208 if (this->
waitUntil (
false,
true, deadline) == -1)
225 if (this->
_state == State::Connected)
227 ::shutdown (this->
_handle, SHUT_WR);
228 this->
_state = State::Disconnecting;
231 if (this->
_state == State::Disconnecting)
239 int result = this->
read (buffer,
sizeof (buffer));
251 ::shutdown (this->
_handle, SHUT_RD);
252 this->
_state = State::Disconnected;
284 if (
JOIN_UNLIKELY ((deadline != TimePoint::max ()) && (this->
_mode == Mode::Blocking)))
290 if ((this->
_state != State::Disconnected) && (this->
_state != State::Closed))
292 if (this->
_state != State::Disconnecting)
300 if (this->
waitUntil (
true,
false, deadline) == -1)
332 ssize_t
read (
char* data,
size_t maxSize)
noexcept
352 return readExactly (data, size, TimePoint::max ());
362 int readExactly (
char* data,
size_t size, std::chrono::nanoseconds timeout)
noexcept
364 return readExactly (data, size, std::chrono::steady_clock::now () + timeout);
376 if (
JOIN_UNLIKELY ((deadline != TimePoint::max ()) && (this->
_mode == Mode::Blocking)))
384 while (numRead < size)
386 ssize_t result = this->
read (data + numRead, size - numRead);
391 if (this->
waitUntil (
true,
false, deadline) == 0)
424 int writeExactly (
const char* data,
size_t size, std::chrono::nanoseconds timeout)
noexcept
426 return writeExactly (data, size, std::chrono::steady_clock::now () + timeout);
438 if (
JOIN_UNLIKELY ((deadline != TimePoint::max ()) && (this->
_mode == Mode::Blocking)))
446 while (numWrite < size)
448 ssize_t result = this->
write (data + numWrite, size - numWrite);
453 if (this->
waitUntil (
false,
true, deadline) == 0)
476 if (this->
_state == State::Closed)
482 int optlevel, optname;
486 case Option::NoDelay:
487 optlevel = IPPROTO_TCP;
488 optname = TCP_NODELAY;
491 case Option::KeepIdle:
492 optlevel = IPPROTO_TCP;
493 optname = TCP_KEEPIDLE;
496 case Option::KeepIntvl:
497 optlevel = IPPROTO_TCP;
498 optname = TCP_KEEPINTVL;
501 case Option::KeepCount:
502 optlevel = IPPROTO_TCP;
503 optname = TCP_KEEPCNT;
510 int result = ::setsockopt (this->
_handle, optlevel, optname, &value,
sizeof (value));
513 lastError = std::error_code (errno, std::generic_category ());
528 struct sockaddr_storage sa;
529 socklen_t sa_len =
sizeof (
struct sockaddr_storage);
531 if (::getpeername (this->
_handle,
reinterpret_cast<struct sockaddr*
> (&sa), &sa_len) != -1)
546 return (this->
_state == State::Connecting);
557 if (this->
_state == State::Connected)
561 else if (this->
_state != State::Connecting)
567 socklen_t optlen =
sizeof (optval);
569 int result = ::getsockopt (this->
_handle, SOL_SOCKET, SO_ERROR, &optval, &optlen);
570 if ((result == -1) || (optval != 0))
575 this->
_state = State::Connected;
586 if (this->
_state == State::Closed)
592 int result = -1, value = -1;
593 socklen_t valueLen =
sizeof (value);
595 if (this->
family () == AF_INET6)
597 result = ::getsockopt (this->
_handle, IPPROTO_IPV6, IPV6_MTU, &value, &valueLen);
599 else if (this->
family () == AF_INET)
601 result = ::getsockopt (this->
_handle, IPPROTO_IP, IP_MTU, &value, &valueLen);
611 lastError = std::error_code (errno, std::generic_category ());
629 template <
class Protocol>
632 return a.handle () < b.handle ();
asynchronous stream socket class.
Definition protocol.hpp:91
basic raw socket class.
Definition raw_socket.hpp:42
typename BasicSocket< Protocol >::Mode Mode
Definition raw_socket.hpp:45
ssize_t write(const char *data, size_t maxSize) noexcept
write data.
Definition raw_socket.hpp:247
typename BasicSocket< Protocol >::State State
Definition raw_socket.hpp:46
Option
socket options.
Definition raw_socket.hpp:53
BasicRawSocket & operator=(const BasicRawSocket &other)=delete
copy assignment operator.
ssize_t read(char *data, size_t maxSize) noexcept
read data.
Definition raw_socket.hpp:211
virtual int setOption(Option option, int value) noexcept
set the given option to the given value.
Definition raw_socket.hpp:277
BasicRawSocket() noexcept
default constructor.
Definition raw_socket.hpp:76
virtual int open(const Protocol &protocol=Protocol()) noexcept
open socket using the given protocol.
Definition socket.hpp:167
std::chrono::steady_clock::time_point TimePoint
Definition socket.hpp:60
Mode mode() const noexcept
get the blocking mode of the socket.
Definition socket.hpp:373
Protocol _protocol
protocol.
Definition socket.hpp:476
Mode _mode
socket mode.
Definition socket.hpp:470
virtual void close() noexcept
close the socket.
Definition socket.hpp:202
int family() const noexcept
get socket address family.
Definition socket.hpp:346
@ NonBlocking
Definition socket.hpp:68
int waitUntil(bool wantRead, bool wantWrite, TimePoint deadline) const noexcept
wait for the socket handle to become ready, giving up at the given time point.
Definition socket.hpp:417
State _state
socket state.
Definition socket.hpp:467
int protocol() const noexcept
get socket protocol.
Definition socket.hpp:364
int _handle
socket handle.
Definition socket.hpp:473
basic stream socket class.
Definition stream_socket.hpp:44
BasicStreamSocket(int fd, const Endpoint &remote, Mode mode=Mode::NonBlocking)
create the socket instance adopting an accepted file descriptor.
Definition stream_socket.hpp:80
BasicStreamSocket(BasicStreamSocket &&other) noexcept
move constructor.
Definition stream_socket.hpp:111
int readExactly(char *data, size_t size, TimePoint deadline) noexcept
read data until size is reached, an error occurred or the deadline expired.
Definition stream_socket.hpp:374
void close() noexcept override
close the socket handle.
Definition stream_socket.hpp:320
~BasicStreamSocket()=default
destroy the instance.
bool waitDisconnected(std::chrono::nanoseconds timeout)
wait until the connection as been shut down, giving up after the given duration.
Definition stream_socket.hpp:272
bool waitConnected()
block until connected.
Definition stream_socket.hpp:178
int setOption(Option option, int value) noexcept override
set the given option to the given value.
Definition stream_socket.hpp:474
BasicStreamSocket(const BasicStreamSocket &other)=delete
copy constructor.
typename BasicRawSocket< Protocol >::Option Option
Definition stream_socket.hpp:52
typename BasicRawSocket< Protocol >::State State
Definition stream_socket.hpp:53
Endpoint _remote
remote endpoint.
Definition stream_socket.hpp:620
bool waitConnected(TimePoint deadline)
block until connected, giving up at the given time point.
Definition stream_socket.hpp:198
bool waitDisconnected(TimePoint deadline)
wait until the connection as been shut down, giving up at the given time point.
Definition stream_socket.hpp:282
bool waitConnected(std::chrono::nanoseconds timeout)
block until connected, giving up after the given duration.
Definition stream_socket.hpp:188
int writeExactly(const char *data, size_t size, std::chrono::nanoseconds timeout) noexcept
write data until size is reached, an error occurred or the given duration elapsed.
Definition stream_socket.hpp:424
typename Protocol::Endpoint Endpoint
Definition stream_socket.hpp:54
std::unique_ptr< BasicStreamSocket< Protocol > > Ptr
Definition stream_socket.hpp:50
int writeExactly(const char *data, size_t size, TimePoint deadline) noexcept
write data until size is reached, an error occurred or the deadline expired.
Definition stream_socket.hpp:436
ssize_t read(char *data, size_t maxSize) noexcept
read data.
Definition stream_socket.hpp:332
BasicStreamSocket & operator=(const BasicStreamSocket &other)=delete
copy assignment operator.
typename BasicRawSocket< Protocol >::Mode Mode
Definition stream_socket.hpp:51
BasicStreamSocket() noexcept
default constructor.
Definition stream_socket.hpp:60
int connect(const Endpoint &endpoint) noexcept
make a connection to the given endpoint.
Definition stream_socket.hpp:141
int readExactly(char *data, size_t size) noexcept
read data until size is reached or an error occurred.
Definition stream_socket.hpp:350
BasicStreamSocket(Mode mode) noexcept
create instance specifying the mode.
Definition stream_socket.hpp:69
bool waitDisconnected()
wait until the connection as been shut down. return true if the connection as been shut down,...
Definition stream_socket.hpp:262
const Endpoint & remoteEndpoint() const noexcept
determine the remote endpoint associated with this socket.
Definition stream_socket.hpp:524
int writeExactly(const char *data, size_t size) noexcept
write data until size is reached or an error occurred.
Definition stream_socket.hpp:412
int disconnect() noexcept
shutdown the connection.
Definition stream_socket.hpp:223
int mtu() const noexcept
get socket mtu.
Definition stream_socket.hpp:584
int readExactly(char *data, size_t size, std::chrono::nanoseconds timeout) noexcept
read data until size is reached, an error occurred or the given duration elapsed.
Definition stream_socket.hpp:362
bool connecting() const noexcept
check if the socket is connecting.
Definition stream_socket.hpp:544
bool connected() noexcept
check if the socket is connected.
Definition stream_socket.hpp:555
typename BasicRawSocket< Protocol >::TimePoint TimePoint
Definition stream_socket.hpp:55
Definition acceptor.hpp:32
bool operator<(const BasicDatagramSocket< Protocol > &a, const BasicDatagramSocket< Protocol > &b) noexcept
compare if socket handle is inferior.
Definition datagram_socket.hpp:394
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:195
#define JOIN_UNLIKELY(x)
Definition utils.hpp:46