Mercurial > code
changeset 381:9fd636045546
Socket:
- Switch to template for addresses,
- Rename Internet to Ip and add Ipv4 and Ipv6 as helpers,
- Split Socket into several different classes.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 23 Jun 2015 14:06:37 +0200 |
parents | 06b0f405c58f |
children | 4b08afed634d |
files | C++/modules/Socket/Socket.cpp C++/modules/Socket/Socket.h C++/modules/Socket/SocketAddress.cpp C++/modules/Socket/SocketAddress.h C++/modules/Socket/SocketListener.cpp C++/modules/Socket/SocketListener.h C++/modules/Socket/SocketSsl.cpp C++/modules/Socket/SocketSsl.h C++/modules/Socket/SocketTcp.cpp C++/modules/Socket/SocketTcp.h C++/modules/Socket/SocketUdp.cpp C++/modules/Socket/SocketUdp.h C++/tests/Socket/main.cpp CMakeLists.txt |
diffstat | 14 files changed, 871 insertions(+), 751 deletions(-) [+] |
line wrap: on
line diff
--- a/C++/modules/Socket/Socket.cpp Fri Jun 19 13:56:12 2015 +0200 +++ b/C++/modules/Socket/Socket.cpp Tue Jun 23 14:06:37 2015 +0200 @@ -26,16 +26,16 @@ * -------------------------------------------------------- */ #if defined(_WIN32) -const Socket::Handle Socket::Invalid{INVALID_SOCKET}; -const int Socket::Error{SOCKET_ERROR}; +const Socket::Handle SocketAbstract::Invalid{INVALID_SOCKET}; +const int SocketAbstract::Error{SOCKET_ERROR}; #else -const int Socket::Invalid{-1}; -const int Socket::Error{-1}; +const int SocketAbstract::Invalid{-1}; +const int SocketAbstract::Error{-1}; #endif #if defined(_WIN32) -std::string Socket::syserror(int errn) +std::string SocketAbstract::syserror(int errn) { LPSTR str = nullptr; std::string errmsg = "Unknown error"; @@ -58,16 +58,14 @@ #else -#include <cerrno> - -std::string Socket::syserror(int errn) +std::string SocketAbstract::syserror(int errn) { return strerror(errn); } #endif -std::string Socket::syserror() +std::string SocketAbstract::syserror() { #if defined(_WIN32) return syserror(WSAGetLastError()); @@ -81,36 +79,36 @@ * -------------------------------------------------------- */ SocketError::SocketError(Code code, std::string function) - : m_code(code) - , m_function(std::move(function)) - , m_error(Socket::syserror()) + : m_code{code} + , m_function{std::move(function)} + , m_error{SocketAbstract::syserror()} { } SocketError::SocketError(Code code, std::string function, int error) - : m_code(code) - , m_function(std::move(function)) - , m_error(Socket::syserror(error)) + : m_code{code} + , m_function{std::move(function)} + , m_error{SocketAbstract::syserror(error)} { } SocketError::SocketError(Code code, std::string function, std::string error) - : m_code(code) - , m_function(std::move(function)) - , m_error(std::move(error)) + : m_code{code} + , m_function{std::move(function)} + , m_error{std::move(error)} { } /* -------------------------------------------------------- - * Socket class + * SocketAbstract class * -------------------------------------------------------- */ #if defined(_WIN32) -std::mutex Socket::s_mutex; -std::atomic<bool> Socket::s_initialized{false}; +std::mutex SocketAbstract::s_mutex; +std::atomic<bool> SocketAbstract::s_initialized{false}; #endif -Socket::Socket(int domain, int type, int protocol) +SocketAbstract::SocketAbstract(int domain, int type, int protocol) { #if defined(_WIN32) && !defined(SOCKET_NO_WSA_INIT) if (!s_initialized) { @@ -121,13 +119,13 @@ m_handle = ::socket(domain, type, protocol); if (m_handle == Invalid) { - throw SocketError(SocketError::System, "socket"); + throw SocketError{SocketError::System, "socket"}; } m_state = SocketState::Opened; } -Socket::Socket(Socket &&other) noexcept +SocketAbstract::SocketAbstract(SocketAbstract &&other) noexcept { m_handle = other.m_handle; m_state = other.m_state; @@ -137,12 +135,14 @@ other.m_state = SocketState::Closed; } -Socket::~Socket() +SocketAbstract::~SocketAbstract() { close(); } -std::unique_ptr<SocketAddress> Socket::address() const +#if 0 + +std::unique_ptr<SocketAddress> SocketAbstract::address() const { socklen_t length; sockaddr_storage ss; @@ -153,7 +153,11 @@ return SocketAddress::decode(ss, length); } -void Socket::bind(const std::unique_ptr<SocketAddress> &address) +#endif + +#if 0 + +void SocketAbstract::bind(const std::unique_ptr<SocketAddress> &address) { const auto &sa = address->address(); const auto addrlen = address->length(); @@ -165,7 +169,9 @@ m_state = SocketState::Bound; } -void Socket::close() +#endif + +void SocketAbstract::close() { if (m_state != SocketState::Closed) { #if defined(_WIN32) @@ -173,12 +179,12 @@ #else ::close(m_handle); #endif - m_handle = -1; + m_handle = Invalid; m_state = SocketState::Closed; } } -void Socket::setBlockMode(bool block) +void SocketAbstract::setBlockMode(bool block) { #if defined(O_NONBLOCK) && !defined(_WIN32) int flags; @@ -194,35 +200,55 @@ } if (fcntl(m_handle, F_SETFL, flags) == Error) { - throw SocketError(SocketError::System, "setBlockMode"); + throw SocketError{SocketError::System, "setBlockMode"}; } #else unsigned long flags = (block) ? 0 : 1; if (ioctlsocket(m_handle, FIONBIO, &flags) == Error) { - throw SocketError(SocketError::System, "setBlockMode"); + throw SocketError{SocketError::System, "setBlockMode"}; } #endif } -Socket &Socket::operator=(Socket &&other) noexcept +SocketAbstract &SocketAbstract::operator=(SocketAbstract &&other) noexcept { m_handle = other.m_handle; m_state = other.m_state; // Invalidate other - other.m_handle = -1; + other.m_handle = Invalid; other.m_state = SocketState::Closed; return *this; } -bool operator==(const Socket &s1, const Socket &s2) +bool operator==(const SocketAbstract &s1, const SocketAbstract &s2) { return s1.handle() == s2.handle(); } -bool operator<(const Socket &s1, const Socket &s2) +bool operator!=(const SocketAbstract &s1, const SocketAbstract &s2) +{ + return s1.handle() != s2.handle(); +} + +bool operator<(const SocketAbstract &s1, const SocketAbstract &s2) { return s1.handle() < s2.handle(); } + +bool operator>(const SocketAbstract &s1, const SocketAbstract &s2) +{ + return s1.handle() > s2.handle(); +} + +bool operator<=(const SocketAbstract &s1, const SocketAbstract &s2) +{ + return s1.handle() <= s2.handle(); +} + +bool operator>=(const SocketAbstract &s1, const SocketAbstract &s2) +{ + return s1.handle() >= s2.handle(); +}
--- a/C++/modules/Socket/Socket.h Fri Jun 19 13:56:12 2015 +0200 +++ b/C++/modules/Socket/Socket.h Tue Jun 23 14:06:37 2015 +0200 @@ -66,6 +66,10 @@ class SocketAddress; +/* -------------------------------------------------------- + * Socket types and errors + * -------------------------------------------------------- */ + /** * @class SocketError * @brief Base class for sockets error @@ -159,11 +163,15 @@ Timeout ///!< Timeout has occured in a waiting operation }; +/* -------------------------------------------------------- + * Generic base sockets + * -------------------------------------------------------- */ + /** * @class Socket * @brief Base socket class for socket operations */ -class Socket { +class SocketAbstract { public: /* {{{ Portable types */ @@ -317,7 +325,7 @@ /** * This create an invalid socket. */ - inline Socket() noexcept + inline SocketAbstract() noexcept : m_handle{Invalid} , m_state{SocketState::Closed} { @@ -328,7 +336,7 @@ * * @param handle the native descriptor */ - inline Socket(Handle handle) noexcept + inline SocketAbstract(Handle handle) noexcept : m_handle{handle} , m_state{SocketState::Opened} { @@ -342,32 +350,24 @@ * @param protocol the protocol * @throw SocketError on failures */ - Socket(int domain, int type, int protocol); + SocketAbstract(int domain, int type, int protocol); /** * Copy constructor deleted. */ - Socket(const Socket &) = delete; + SocketAbstract(const SocketAbstract &) = delete; /** * Transfer ownership from other to this. * * @param other the other socket */ - Socket(Socket &&other) noexcept; + SocketAbstract(SocketAbstract &&other) noexcept; /** * Default destructor. */ - virtual ~Socket(); - - /** - * Get the local name. This is a wrapper of getsockname(). - * - * @return the address - * @throw SocketError on failures - */ - std::unique_ptr<SocketAddress> address() const; + virtual ~SocketAbstract(); /** * Set an option for the socket. @@ -381,11 +381,11 @@ inline void set(int level, int name, const Argument &arg) { #if defined(_WIN32) - if (setsockopt(m_handle, level, name, (Socket::ConstArg)&arg, sizeof (arg)) == Error) + if (setsockopt(m_handle, level, name, (SocketAbstract::ConstArg)&arg, sizeof (arg)) == Error) #else - if (setsockopt(m_handle, level, name, (Socket::ConstArg)&arg, sizeof (arg)) < 0) + if (setsockopt(m_handle, level, name, (SocketAbstract::ConstArg)&arg, sizeof (arg)) < 0) #endif - throw SocketError(SocketError::System, "set"); + throw SocketError{SocketError::System, "set"}; } /** @@ -402,11 +402,11 @@ socklen_t size = sizeof (result); #if defined(_WIN32) - if (getsockopt(m_handle, level, name, (Socket::Arg)&desired, &size) == Error) + if (getsockopt(m_handle, level, name, (SocketAbstract::Arg)&desired, &size) == Error) #else - if (getsockopt(m_handle, level, name, (Socket::Arg)&desired, &size) < 0) + if (getsockopt(m_handle, level, name, (SocketAbstract::Arg)&desired, &size) < 0) #endif - throw SocketError(SocketError::System, "get"); + throw SocketError{SocketError::System, "get"}; std::memcpy(&result, &desired, size); @@ -435,14 +435,6 @@ } /** - * Bind to an address. - * - * @param address the address - * @throw SocketError on any error - */ - void bind(const std::unique_ptr<SocketAddress> &address); - - /** * Set the blocking mode, if set to false, the socket will be marked * **non-blocking**. * @@ -463,7 +455,7 @@ * * @return *this */ - Socket &operator=(const Socket &) = delete; + SocketAbstract &operator=(const SocketAbstract &) = delete; /** * Transfer ownership from other to this. The other socket is left @@ -472,9 +464,523 @@ * @param other the other socket * @return this */ - Socket &operator=(Socket &&other) noexcept; + SocketAbstract &operator=(SocketAbstract &&other) noexcept; +}; + +/** + * @class Socket + * @brief Generic socket implementation + * + * This class can be used to bind a socket and access its address. + * + * @see SocketAbstractTcp + * @see SocketAbstractUdp + */ +template <typename Address> +class Socket : public SocketAbstract { +public: + /** + * Inherited constructors. + */ + using SocketAbstract::SocketAbstract; + + /** + * Bind to an address. + * + * @param address the address + * @throw SocketError on any error + */ + inline void bind(const Address &address) + { + const auto &sa = address.address(); + const auto addrlen = address.length(); + + if (::bind(m_handle, reinterpret_cast<const sockaddr *>(&sa), addrlen) == Error) { + throw SocketError{SocketError::System, "bind"}; + } + + m_state = SocketState::Bound; + } + + /** + * Get the local name. This is a wrapper of getsockname(). + * + * @return the address + * @throw SocketError on failures + */ + inline Address address() const + { + socklen_t length; + sockaddr_storage ss; + + if (getsockname(m_handle, (sockaddr *)&ss, &length) == Error) { + throw SocketError{SocketError::System, "getsockname"}; + } + + return Address(ss, length); + } +}; + +/* -------------------------------------------------------- + * TCP Sockets + * -------------------------------------------------------- */ + +/** + * @class SocketAbstractTcp + * @brief Base class for TCP sockets + * @see SocketTcp + * @see SocketSsl + */ +template <typename Address> +class SocketAbstractTcp : public Socket<Address> { +public: + /** + * Inherited constructors. + */ + using Socket<Address>::Socket; + + /** + * Construct a standard TCP socket. The type is automatically + * set to SOCK_STREAM. + * + * @param domain the domain + * @param protocol the protocol + * @throw SocketError on error + */ + inline SocketAbstractTcp(int domain, int protocol) + : Socket<Address>(domain, SOCK_STREAM, protocol) + { + } + + /** + * Listen for pending connection. + * + * @param max the maximum number + */ + inline void listen(int max = 128) + { + if (::listen(Socket<Address>::m_handle, max) == SocketAbstract::Error) { + throw SocketError{SocketError::System, "listen"}; + } + } + + /** + * Receive some data. + * + * @param data the destination buffer + * @param length the buffer length + * @throw SocketError on error + */ + virtual unsigned recv(void *data, unsigned length) = 0; + + /** + * Send some data. + * + * @param data the data buffer + * @param length the buffer length + * @throw SocketError on error + */ + virtual unsigned send(const void *data, unsigned length) = 0; + + /** + * Overloaded function. + * + * @param count the number of bytes to receive + * @return the string + * @throw SocketError on error + */ + inline std::string recv(unsigned count) + { + std::string result; + + result.resize(count); + auto n = recv(const_cast<char *>(result.data()), count); + result.resize(n); + + return result; + } + + /** + * Overloaded function. + * + * @param data the string to send + * @return the number of bytes sent + * @throw SocketError on error + */ + inline unsigned send(const std::string &data) + { + return send(data.c_str(), data.size()); + } +}; + +/** + * @class SocketTcp + * @brief Standard implementation of TCP sockets + * + * This class is the basic implementation of TCP sockets. + */ +template <typename Address> +class SocketTcp : public SocketAbstractTcp<Address> { +public: + /** + * Inherited constructors. + */ + using SocketAbstractTcp<Address>::SocketAbstractTcp; + + /** + * Connect to an end point. + * + * @param address the address + * @throw SocketError on error + */ + void connect(const Address &address); + + /** + * Overloaded function. + */ + inline SocketTcp accept() + { + Address dummy; + + return accept(dummy); + } + + /** + * Accept a clear TCP socket. + * + * @param info the client information + * @return the socket + * @throw SocketError on error + */ + SocketTcp accept(Address &info); + + /** + * @copydoc SocketAbstractTcp<Address>::recv + */ + using SocketAbstractTcp<Address>::recv; + + /** + * @copydoc SocketAbstractTcp<Address>::send + */ + using SocketAbstractTcp<Address>::send; + + /** + * @copydoc SocketAbstractTcp<Address>::recv + */ + unsigned recv(void *data, unsigned length) override; + + /** + * @copydoc SocketAbstractTcp<Address>::send + */ + unsigned send(const void *data, unsigned length) override; }; +template <typename Address> +void SocketTcp<Address>::connect(const Address &address) +{ + if (SocketAbstract::m_state == SocketState::Connected) { + return; + } + + auto &sa = address.address(); + auto addrlen = address.length(); + + if (::connect(SocketAbstract::m_handle, reinterpret_cast<const sockaddr *>(&sa), addrlen) == SocketAbstract::Error) { + /* + * Determine if the error comes from a non-blocking connect that cannot be + * accomplished yet. + */ +#if defined(_WIN32) + int error = WSAGetLastError(); + + if (error == WSAEWOULDBLOCK) { + throw SocketError{SocketError::WouldBlockWrite, "connect", error}; + } + + throw SocketError{SocketError::System, "connect", error}; +#else + if (errno == EINPROGRESS) { + throw SocketError{SocketError::WouldBlockWrite, "connect"}; + } + + throw SocketError{SocketError::System, "connect"}; +#endif + } + + SocketAbstract::m_state = SocketState::Connected; +} + +template <typename Address> +unsigned SocketTcp<Address>::recv(void *data, unsigned dataLen) +{ + int nbread; + + nbread = ::recv(SocketAbstract::m_handle, (SocketAbstract::Arg)data, dataLen, 0); + if (nbread == SocketAbstract::Error) { +#if defined(_WIN32) + int error = WSAGetLastError(); + + if (error == WSAEWOULDBLOCK) { + throw SocketError{SocketError::WouldBlockRead, "recv", error}; + } + + throw SocketError{SocketError::System, "recv", error}; +#else + if (errno == EAGAIN || errno == EWOULDBLOCK) { + throw SocketError{SocketError::WouldBlockRead, "recv"}; + } + + throw SocketError{SocketError::System, "recv"}; +#endif + } else if (nbread == 0) { + SocketAbstract::m_state = SocketState::Closed; + } + + return static_cast<unsigned>(nbread); +} + +template <typename Address> +unsigned SocketTcp<Address>::send(const void *data, unsigned length) +{ + int nbsent; + + nbsent = ::send(SocketAbstract::m_handle, (SocketAbstract::ConstArg)data, length, 0); + if (nbsent == SocketAbstract::Error) { +#if defined(_WIN32) + int error = WSAGetLastError(); + + if (error == WSAEWOULDBLOCK) { + throw SocketError{SocketError::WouldBlockWrite, "send", error}; + } + + throw SocketError{SocketError::System, "send", error}; +#else + if (errno == EAGAIN || errno == EWOULDBLOCK) { + throw SocketError{SocketError::WouldBlockWrite, "send"}; + } + + throw SocketError{SocketError::System, "send"}; +#endif + } + + return static_cast<unsigned>(nbsent); +} + +template <typename Address> +SocketTcp<Address> SocketTcp<Address>::accept(Address &info) +{ + SocketAbstract::Handle handle; + + // Store the information + sockaddr_storage address; + socklen_t addrlen; + + addrlen = sizeof (sockaddr_storage); + handle = ::accept(SocketAbstract::m_handle, reinterpret_cast<sockaddr *>(&address), &addrlen); + + if (handle == SocketAbstract::Invalid) { +#if defined(_WIN32) + int error = WSAGetLastError(); + + if (error == WSAEWOULDBLOCK) { + throw SocketError{SocketError::WouldBlockRead, "accept", error}; + } + + throw SocketError{SocketError::System, "accept", error}; +#else + if (errno == EAGAIN || errno == EWOULDBLOCK) { + throw SocketError{SocketError::WouldBlockRead, "accept"}; + } + + throw SocketError{SocketError::System, "accept"}; +#endif + } + + info = Address{address, addrlen}; + + return SocketTcp{handle}; +} + +/* -------------------------------------------------------- + * UDP Sockets + * -------------------------------------------------------- */ + +/** + * @class SocketAbstractUdp + * @brief Base class for UDP sockets + * @see SocketUdp + */ +template <typename Address> +class SocketAbstractUdp : public Socket<Address> { +public: + /** + * Inherited constructors. + */ + using Socket<Address>::Socket; + + /** + * Construct a UDP socket. The type is automatically set to SOCK_DGRAM. + * + * @param domain the domain (e.g AF_INET) + * @param protocol the protocol (usually 0) + */ + inline SocketAbstractUdp(int domain, int protocol) + : Socket<Address>(domain, SOCK_DGRAM, protocol) + { + } + + /** + * Overloaded function. + * + * @param data the data + * @param address the address + * @return the number of bytes sent + * @throw SocketError on error + */ + inline unsigned sendto(const std::string &data, const Address &address) + { + return sendto(data.c_str(), data.length(), address); + } + + /** + * Overloaded function. + * + * @param data the data + * @param info the client information + * @return the string + * @throw SocketError on error + */ + inline std::string recvfrom(unsigned count, Address &info) + { + std::string result; + + result.resize(count); + auto n = recvfrom(const_cast<char *>(result.data()), count, info); + result.resize(n); + + return result; + } + + /** + * Receive data from an end point. + * + * @param data the destination buffer + * @param length the buffer length + * @param info the client information + * @return the number of bytes received + * @throw SocketError on error + */ + virtual unsigned recvfrom(void *data, unsigned length, Address &info) = 0; + + /** + * Send data to an end point. + * + * @param data the buffer + * @param length the buffer length + * @param address the client address + * @return the number of bytes sent + * @throw SocketError on error + */ + virtual unsigned sendto(const void *data, unsigned length, const Address &address) = 0; +}; + +/** + * @class SocketUdp + * @brief Standard implementation of UDP sockets + * + * This class is the basic implementation of UDP sockets. + */ +template <typename Address> +class SocketUdp : public SocketAbstractUdp<Address> { +public: + /** + * Inherited constructors. + */ + using SocketAbstractUdp<Address>::SocketAbstractUdp; + + /** + * @copydoc SocketAbstractUdp<Address>::recv + */ + using SocketAbstractUdp<Address>::recvfrom; + + /** + * @copydoc SocketAbstractUdp<Address>::send + */ + using SocketAbstractUdp<Address>::sendto; + + /** + * @copydoc SocketAbstractUdp<Address>::recvfrom + */ + unsigned recvfrom(void *data, unsigned length, Address &info) override; + + /** + * @copydoc SocketAbstractUdp<Address>::sendto + */ + unsigned sendto(const void *data, unsigned length, const Address &address) override; +}; + +template <typename Address> +unsigned SocketUdp<Address>::recvfrom(void *data, unsigned length, Address &info) +{ + int nbread; + + // Store information + sockaddr_storage address; + socklen_t addrlen; + + addrlen = sizeof (struct sockaddr_storage); + nbread = ::recvfrom(SocketAbstract::m_handle, (SocketAbstract::Arg)data, length, 0, (sockaddr *)&address, &addrlen); + + info = Address{address, addrlen}; + + if (nbread == SocketAbstract::Error) { +#if defined(_WIN32) + int error = WSAGetLastError(); + + if (error == WSAEWOULDBLOCK) { + throw SocketError{SocketError::WouldBlockRead, "recvfrom", error}; + } + + throw SocketError{SocketError::System, "recvfrom", error}; +#else + if (errno == EAGAIN || errno == EWOULDBLOCK) { + throw SocketError{SocketError::WouldBlockRead, "recvfrom"}; + } + + throw SocketError{SocketError::System, "recvfrom"}; +#endif + } + + return static_cast<unsigned>(nbread); +} + +template <typename Address> +unsigned SocketUdp<Address>::sendto(const void *data, unsigned length, const Address &info) +{ + int nbsent; + + nbsent = ::sendto(SocketAbstract::m_handle, (SocketAbstract::ConstArg)data, length, 0, (const sockaddr *)&info.address(), info.length()); + if (nbsent == SocketAbstract::Error) { +#if defined(_WIN32) + int error = WSAGetLastError(); + + if (error == WSAEWOULDBLOCK) { + throw SocketError{SocketError::WouldBlockWrite, "sendto", error}; + } + + throw SocketError{SocketError::System, "sendto", error}; +#else + if (errno == EAGAIN || errno == EWOULDBLOCK) { + throw SocketError{SocketError::WouldBlockWrite, "sendto"}; + } + + throw SocketError{SocketError::System, "sendto"}; +#endif + } + + return static_cast<unsigned>(nbsent); +} + /** * Compare two sockets. * @@ -482,15 +988,51 @@ * @param s2 the second socket * @return true if they equals */ -bool operator==(const Socket &s1, const Socket &s2); +bool operator==(const SocketAbstract &s1, const SocketAbstract &s2); /** - * Compare two sockets, ideal for putting in a std::map. + * Compare two sockets. + * + * @param s1 the first socket + * @param s2 the second socket + * @return true if they are different + */ +bool operator!=(const SocketAbstract &s1, const SocketAbstract &s2); + +/** + * Compare two sockets. * * @param s1 the first socket * @param s2 the second socket * @return true if s1 < s2 */ -bool operator<(const Socket &s1, const Socket &s2); +bool operator<(const SocketAbstract &s1, const SocketAbstract &s2); + +/** + * Compare two sockets. + * + * @param s1 the first socket + * @param s2 the second socket + * @return true if s1 > s2 + */ +bool operator>(const SocketAbstract &s1, const SocketAbstract &s2); + +/** + * Compare two sockets. + * + * @param s1 the first socket + * @param s2 the second socket + * @return true if s1 <= s2 + */ +bool operator<=(const SocketAbstract &s1, const SocketAbstract &s2); + +/** + * Compare two sockets. + * + * @param s1 the first socket + * @param s2 the second socket + * @return true if s1 >= s2 + */ +bool operator>=(const SocketAbstract &s1, const SocketAbstract &s2); #endif // !_SOCKET_NG_H_
--- a/C++/modules/Socket/SocketAddress.cpp Fri Jun 19 13:56:12 2015 +0200 +++ b/C++/modules/Socket/SocketAddress.cpp Tue Jun 23 14:06:37 2015 +0200 @@ -22,30 +22,13 @@ #include "Socket.h" #include "SocketAddress.h" -std::unique_ptr<SocketAddress> SocketAddress::decode(const struct sockaddr_storage &ss, socklen_t length) -{ - switch (ss.ss_family) { - case AF_INET: - case AF_INET6: - return std::make_unique<address::Internet>(ss, length); -#if !defined(_WIN32) - case AF_UNIX: - return std::make_unique<address::Unix>(ss, length); -#endif - default: - break; - } - - throw std::invalid_argument{"not a valid address type"}; -} - namespace address { /* -------------------------------------------------------- - * Internet implementation + * Ip implementation * -------------------------------------------------------- */ -Internet::Internet(const std::string &host, unsigned port, int domain) +Ip::Ip(const std::string &host, unsigned port, int domain) : m_domain{domain} { if (host == "*") { @@ -83,7 +66,7 @@ } } -Internet::Internet(const sockaddr_storage &ss, socklen_t length) +Ip::Ip(const sockaddr_storage &ss, socklen_t length) : m_domain{ss.ss_family} { if (ss.ss_family == AF_INET6) { @@ -93,21 +76,7 @@ } } -socklen_t Internet::length() const noexcept -{ - return (m_domain == AF_INET6) ? sizeof (struct sockaddr_in6) : sizeof (struct sockaddr_in); -} - -const sockaddr &Internet::address() const noexcept -{ - // Can't get a ternary operator to work here. - if (m_domain == AF_INET6) - return reinterpret_cast<const sockaddr &>(m_sin6); - - return reinterpret_cast<const sockaddr &>(m_sin); -} - -SocketAddressInfo Internet::info() const +SocketAddressInfo Ip::info() const { std::string type = (m_domain == AF_INET6) ? "ipv6" : "ipv4"; std::string port = std::to_string(m_domain == AF_INET6 ? ntohs(m_sin6.sin6_port) : ntohs(m_sin.sin_port)); @@ -134,29 +103,19 @@ // Copy the path memset(m_sun.sun_path, 0, sizeof (m_sun.sun_path)); - strncpy(m_sun.sun_path, path.c_str(), sizeof (m_sun.sun_path) - 1); + strncpy(m_sun.sun_path, m_path.c_str(), sizeof (m_sun.sun_path) - 1); // Set the parameters m_sun.sun_family = AF_UNIX; } -Unix::Unix(const sockaddr_storage &ss, socklen_t) -{ - m_path = reinterpret_cast<const struct sockaddr_un &>(ss).sun_path; -} - -socklen_t Unix::length() const noexcept +Unix::Unix(const sockaddr_storage &ss, socklen_t length) { -#if defined(SOCKET_HAVE_SUN_LEN) - return SUN_LEN(m_sun); -#else - return sizeof (m_sun); -#endif -} + std::memcpy(&m_sun, &ss, length); -const sockaddr &Unix::address() const noexcept -{ - return reinterpret_cast<const sockaddr &>(m_sun); + if (ss.ss_family == AF_UNIX) { + m_path = reinterpret_cast<const sockaddr_un &>(m_sun).sun_path; + } } SocketAddressInfo Unix::info() const
--- a/C++/modules/Socket/SocketAddress.h Fri Jun 19 13:56:12 2015 +0200 +++ b/C++/modules/Socket/SocketAddress.h Tue Jun 23 14:06:37 2015 +0200 @@ -29,7 +29,6 @@ * compute the address size for a Unix address. Otherwise, sizeof is used. */ - #include <memory> #include <string> #include <unordered_map> @@ -44,7 +43,6 @@ # include <netinet/in.h> #endif - /** * Generic information table for an address. */ @@ -63,16 +61,6 @@ class SocketAddress { public: /** - * Decode an address into the appropriate object. Useful for recvfrom, accept. - * - * @param ss the storage address - * @param length the address length - * @return the real object - * @throw std::invalid_argument on error - */ - static std::unique_ptr<SocketAddress> decode(const struct sockaddr_storage &ss, socklen_t length); - - /** * Default constructor. */ SocketAddress() = default; @@ -81,39 +69,18 @@ * Default destructor. */ virtual ~SocketAddress() = default; - - /** - * Get the address length - * - * @return the length - */ - virtual socklen_t length() const noexcept = 0; - - /** - * Get the address. - * - * @return the address - */ - virtual const sockaddr &address() const noexcept = 0; - - /** - * Get the information about the address. - * - * @return the information - */ - virtual SocketAddressInfo info() const = 0; }; namespace address { /** - * @class Internet + * @class Ip * @brief internet protocol connect class * * Create a connect address for internet protocol, * using getaddrinfo(3). */ -class Internet : public SocketAddress { +class Ip : public SocketAddress { private: union { struct sockaddr_in m_sin; @@ -124,6 +91,11 @@ public: /** + * Default constructor. + */ + Ip() = default; + + /** * Create an IPv4 or IPV6 end point. * * @param host the hostname @@ -131,7 +103,7 @@ * @param domain AF_INET or AF_INET6 * @throw SocketError on error */ - Internet(const std::string &host, unsigned port, int domain); + Ip(const std::string &host, unsigned port, int domain); /** * Construct an internet address from a storage address. @@ -139,22 +111,68 @@ * @param ss the storage * @param length the length */ - Internet(const struct sockaddr_storage &ss, socklen_t length); + Ip(const sockaddr_storage &ss, socklen_t length); /** * @copydoc SocketAddress::length */ - socklen_t length() const noexcept override; + socklen_t length() const noexcept + { + return (m_domain == AF_INET6) ? sizeof (sockaddr_in6) : sizeof (sockaddr_in); + } /** * @copydoc SocketAddress::address */ - const sockaddr &address() const noexcept override; + const sockaddr &address() const noexcept + { + // Can't get a ternary operator to work here. + if (m_domain == AF_INET6) + return reinterpret_cast<const sockaddr &>(m_sin6); + + return reinterpret_cast<const sockaddr &>(m_sin); + } /** * @copydoc SocketAddress::info */ - SocketAddressInfo info() const override; + SocketAddressInfo info() const; +}; + +class Ipv6 : public Ip { +public: + /** + * Default constructor. + */ + Ipv6() = default; + + inline Ipv6(const sockaddr_storage &ss, socklen_t length) + : Ip(ss, length) + { + } + + inline Ipv6(const std::string &host, unsigned port) + : Ip(host, port, AF_INET6) + { + } +}; + +class Ipv4 : public Ip { +public: + /** + * Default constructor. + */ + Ipv4() = default; + + inline Ipv4(const sockaddr_storage &ss, socklen_t length) + : Ip(ss, length) + { + } + + inline Ipv4(const std::string &host, unsigned port) + : Ip(host, port, AF_INET) + { + } }; #if !defined(_WIN32) @@ -171,6 +189,8 @@ std::string m_path; public: + Unix() = default; + /** * Construct an address to a path. * @@ -185,25 +205,35 @@ * @param ss the storage * @param length the length */ - Unix(const struct sockaddr_storage &ss, socklen_t length); + Unix(const sockaddr_storage &ss, socklen_t length); /** * @copydoc SocketAddress::length */ - socklen_t length() const noexcept override; + inline socklen_t length() const noexcept + { +#if defined(SOCKET_HAVE_SUN_LEN) + return SUN_LEN(&m_sun); +#else + return sizeof (m_sun); +#endif + } /** * @copydoc SocketAddress::address */ - const sockaddr &address() const noexcept override; + inline const sockaddr &address() const noexcept + { + return reinterpret_cast<const sockaddr &>(m_sun); + } /** * @copydoc SocketAddress::info */ - SocketAddressInfo info() const override; + SocketAddressInfo info() const; }; -#endif // ! !_WIN32 +#endif // !_WIN32 } // !address
--- a/C++/modules/Socket/SocketListener.cpp Fri Jun 19 13:56:12 2015 +0200 +++ b/C++/modules/Socket/SocketListener.cpp Tue Jun 23 14:06:37 2015 +0200 @@ -36,7 +36,7 @@ FD_ZERO(&readset); FD_ZERO(&writeset); - Socket::Handle max = 0; + SocketAbstract::Handle max = 0; for (const auto &s : table) { if (s.second.second & SocketListener::Read) { @@ -58,7 +58,7 @@ towait = (ms < 0) ? nullptr : &maxwait; auto error = ::select(max + 1, &readset, &writeset, nullptr, towait); - if (error == Socket::Error) { + if (error == SocketAbstract::Error) { throw SocketError(SocketError::System, "select"); } if (error == 0) { @@ -69,10 +69,10 @@ for (auto &c : table) { if (FD_ISSET(c.first, &readset)) { - sockets.push_back(SocketStatus{c.second.first, SocketListener::Read}); + sockets.push_back(SocketStatus{*c.second.first, SocketListener::Read}); } if (FD_ISSET(c.first, &writeset)) { - sockets.push_back(SocketStatus{c.second.first, SocketListener::Write}); + sockets.push_back(SocketStatus{*c.second.first, SocketListener::Write}); } } @@ -127,23 +127,23 @@ return flags; } -void Poll::set(const SocketTable &, const std::shared_ptr<Socket> s, int flags, bool add) +void Poll::set(const SocketTable &, SocketAbstract &s, int flags, bool add) { if (add) { - m_fds.push_back(pollfd{s->handle(), topoll(flags), 0}); + m_fds.push_back(pollfd{s.handle(), topoll(flags), 0}); } else { auto it = std::find_if(m_fds.begin(), m_fds.end(), [&] (const struct pollfd &pfd) { - return pfd.fd == s->handle(); + return pfd.fd == s.handle(); }); it->events |= topoll(flags); } } -void Poll::unset(const SocketTable &, const std::shared_ptr<Socket> s, int flags, bool remove) +void Poll::unset(const SocketTable &, SocketAbstract &s, int flags, bool remove) { auto it = std::find_if(m_fds.begin(), m_fds.end(), [&] (const struct pollfd &pfd) { - return pfd.fd == s->handle(); + return pfd.fd == s.handle(); }); if (remove) { @@ -166,7 +166,7 @@ std::vector<SocketStatus> sockets; for (auto &fd : m_fds) { if (fd.revents != 0) { - sockets.push_back(SocketStatus{table.at(fd.fd).first, toflags(fd.revents)}); + sockets.push_back(SocketStatus{*table.at(fd.fd).first, toflags(fd.revents)}); } } @@ -209,16 +209,16 @@ return flags; } -void Epoll::update(const std::shared_ptr<Socket> &sc, int op, int flags) +void Epoll::update(SocketAbstract &sc, int op, int flags) { struct epoll_event ev; std::memset(&ev, 0, sizeof (struct epoll_event)); ev.events = flags; - ev.data.fd = sc->handle(); + ev.data.fd = sc.handle(); - if (epoll_ctl(m_handle, op, sc->handle(), &ev) < 0) { + if (epoll_ctl(m_handle, op, sc.handle(), &ev) < 0) { throw SocketError{SocketError::System, "epoll_ctl"}; } } @@ -239,7 +239,7 @@ /* * Add a new epoll_event or just update it. */ -void Epoll::set(const SocketTable &, const std::shared_ptr<Socket> &sc, int flags, bool add) +void Epoll::set(const SocketTable &, SocketAbstract &sc, int flags, bool add) { update(sc, add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, toepoll(flags)); @@ -256,13 +256,13 @@ * So we put the same flags that are currently effective and remove the * requested one. */ -void Epoll::unset(const SocketTable &table, const std::shared_ptr<Socket> &sc, int flags, bool remove) +void Epoll::unset(const SocketTable &table, SocketAbstract &sc, int flags, bool remove) { if (remove) { update(sc, EPOLL_CTL_DEL, 0); m_events.resize(m_events.size() - 1); } else { - update(sc, EPOLL_CTL_MOD, table.at(sc->handle()).second & ~(toepoll(flags))); + update(sc, EPOLL_CTL_MOD, table.at(sc.handle()).second & ~(toepoll(flags))); } } @@ -279,7 +279,7 @@ } for (int i = 0; i < ret; ++i) { - result.push_back(SocketStatus{table.at(m_events[i].data.fd).first, toflags(m_events[i].events)}); + result.push_back(SocketStatus{*table.at(m_events[i].data.fd).first, toflags(m_events[i].events)}); } return result; @@ -306,18 +306,18 @@ close(m_handle); } -void Kqueue::update(const std::shared_ptr<Socket> &sc, int filter, int flags) +void Kqueue::update(SocketAbstract &sc, int filter, int flags) { struct kevent ev; - EV_SET(&ev, sc->handle(), filter, flags, 0, 0, nullptr); + EV_SET(&ev, sc.handle(), filter, flags, 0, 0, nullptr); if (kevent(m_handle, &ev, 1, nullptr, 0, nullptr) < 0) { throw SocketError(SocketError::System, "kevent"); } } -void Kqueue::set(const SocketTable &, const std::shared_ptr<Socket> &sc, int flags, bool add) +void Kqueue::set(const SocketTable &, SocketAbstract &sc, int flags, bool add) { if (flags & SocketListener::Read) { update(sc, EVFILT_READ, EV_ADD | EV_ENABLE); @@ -331,7 +331,7 @@ } } -void Kqueue::unset(const SocketTable &, const std::shared_ptr<Socket> &sc, int flags, bool remove) +void Kqueue::unset(const SocketTable &, SocketAbstract &sc, int flags, bool remove) { if (flags & SocketListener::Read) { update(sc, EVFILT_READ, EV_DELETE); @@ -364,10 +364,10 @@ } for (int i = 0; i < nevents; ++i) { - std::shared_ptr<Socket> sc = table.at(m_result[i].ident).first; + Socket *sc = table.at(m_result[i].ident).first; int flags = m_result[i].filter == EVFILT_READ ? SocketListener::Read : SocketListener::Write; - sockets.push_back(SocketStatus{sc, flags}); + sockets.push_back(SocketStatus{*sc, flags}); } return sockets;
--- a/C++/modules/Socket/SocketListener.h Fri Jun 19 13:56:12 2015 +0200 +++ b/C++/modules/Socket/SocketListener.h Tue Jun 23 14:06:37 2015 +0200 @@ -105,15 +105,15 @@ */ class SocketStatus { public: - std::shared_ptr<Socket> socket; //!< which socket is ready - int flags; //!< the flags + SocketAbstract &socket; //!< which socket is ready + int flags; //!< the flags }; /** * Table used in the socket listener to store which sockets have been * set in which directions. */ -using SocketTable = std::map<Socket::Handle, std::pair<std::shared_ptr<Socket>, int>>; +using SocketTable = std::map<SocketAbstract::Handle, std::pair<SocketAbstract *, int>>; namespace backend { @@ -136,12 +136,12 @@ /** * No-op, uses the SocketTable directly. */ - inline void set(const SocketTable &, const std::shared_ptr<Socket> &, int, bool) noexcept {} + inline void set(const SocketTable &, SocketAbstract &, int, bool) noexcept {} /** * No-op, uses the SocketTable directly. */ - inline void unset(const SocketTable &, const std::shared_ptr<Socket> &, int, bool) noexcept {} + inline void unset(const SocketTable &, SocketAbstract &, int, bool) noexcept {} std::vector<SocketStatus> wait(const SocketTable &table, int ms); }; @@ -163,8 +163,8 @@ int toflags(short &event) const noexcept; public: - void set(const SocketTable &, const std::shared_ptr<Socket> sc, int flags, bool add); - void unset(const SocketTable &, const std::shared_ptr<Socket> sc, int flags, bool remove); + void set(const SocketTable &, SocketAbstract &sc, int flags, bool add); + void unset(const SocketTable &, SocketAbstract &sc, int flags, bool remove); std::vector<SocketStatus> wait(const SocketTable &, int ms); /** @@ -192,13 +192,13 @@ uint32_t toepoll(int flags) const noexcept; int toflags(uint32_t events) const noexcept; - void update(const std::shared_ptr<Socket> &sc, int op, int flags); + void update(SocketAbstract &sc, int op, int flags); public: Epoll(); ~Epoll(); - void set(const SocketTable &, const std::shared_ptr<Socket> &sc, int flags, bool add); - void unset(const SocketTable &, const std::shared_ptr<Socket> &sc, int flags, bool remove); + void set(const SocketTable &, SocketAbstract &sc, int flags, bool add); + void unset(const SocketTable &, SocketAbstract &sc, int flags, bool remove); std::vector<SocketStatus> wait(const SocketTable &table, int ms); /** @@ -237,8 +237,8 @@ Kqueue(); ~Kqueue(); - void set(const SocketTable &, const std::shared_ptr<Socket> &sc, int flags, bool add); - void unset(const SocketTable &, const std::shared_ptr<Socket> &sc, int flags, bool remove); + void set(const SocketTable &, SocketAbstract &sc, int flags, bool add); + void unset(const SocketTable &, SocketAbstract &sc, int flags, bool remove); std::vector<SocketStatus> wait(const SocketTable &, int ms); /** @@ -274,7 +274,7 @@ * # Set * * @code - * void set(const SocketTable &, const std::shared_ptr<Socket> &sc, int flags, bool add); + * void set(const SocketTable &, const SocketAbstract &sc, int flags, bool add); * @endcode * * This function, takes the socket to be added and the flags. The flags are @@ -288,7 +288,7 @@ * # Unset * * @code - * void unset(const SocketTable &, const std::shared_ptr<Socket> &sc, int flags, bool remove); + * void unset(const SocketTable &, const SocketAbstract &sc, int flags, bool remove); * @endcode * * Like set, this function is only called if the flags are actually set and will @@ -339,6 +339,8 @@ { } +#if 0 + /** * Create a listener from a list of sockets. * @@ -350,6 +352,7 @@ set(p.first, p.second); } } +#endif /** * Get the backend. @@ -423,7 +426,7 @@ * @param flags (may be OR'ed) * @throw SocketError if the backend failed to set */ - void set(const std::shared_ptr<Socket> &sc, int flags); + void set(SocketAbstract &sc, int flags); /** * Unset a socket from the listener, only the flags is removed @@ -436,7 +439,7 @@ * @param flags the flags (may be OR'ed) * @see remove */ - void unset(const std::shared_ptr<Socket> &sc, int flags); + void unset(SocketAbstract &sc, int flags); /** * Remove completely the socket from the listener. @@ -445,7 +448,7 @@ * * @param sc the socket */ - inline void remove(std::shared_ptr<Socket> sc) + inline void remove(SocketAbstract &sc) { unset(sc, Read | Write); } @@ -519,13 +522,13 @@ }; template <typename Backend> -void SocketListenerBase<Backend>::set(const std::shared_ptr<Socket> &sc, int flags) +void SocketListenerBase<Backend>::set(SocketAbstract &sc, int flags) { /* Invalid or useless flags */ if (flags == 0 || flags > 0x3) return; - auto it = m_table.find(sc->handle()); + auto it = m_table.find(sc.handle()); /* * Do not update the table if the backend failed to add @@ -533,7 +536,7 @@ */ if (it == m_table.end()) { m_backend.set(m_table, sc, flags, true); - m_table.emplace(sc->handle(), std::make_pair(sc, flags)); + m_table.emplace(sc.handle(), std::make_pair(std::addressof(sc), flags)); } else { if ((flags & Read) && (it->second.second & Read)) { flags &= ~(Read); @@ -551,9 +554,9 @@ } template <typename Backend> -void SocketListenerBase<Backend>::unset(const std::shared_ptr<Socket> &sc, int flags) +void SocketListenerBase<Backend>::unset(SocketAbstract &sc, int flags) { - auto it = m_table.find(sc->handle()); + auto it = m_table.find(sc.handle()); /* Invalid or useless flags */ if (flags == 0 || flags > 0x3 || it == m_table.end())
--- a/C++/modules/Socket/SocketSsl.cpp Fri Jun 19 13:56:12 2015 +0200 +++ b/C++/modules/Socket/SocketSsl.cpp Tue Jun 23 14:06:37 2015 +0200 @@ -16,6 +16,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if 0 + #include "SocketAddress.h" #include "SocketSsl.h" @@ -165,3 +167,5 @@ return nbread; } + +#endif
--- a/C++/modules/Socket/SocketSsl.h Fri Jun 19 13:56:12 2015 +0200 +++ b/C++/modules/Socket/SocketSsl.h Tue Jun 23 14:06:37 2015 +0200 @@ -19,6 +19,8 @@ #ifndef _SOCKET_SSL_NG_H_ #define _SOCKET_SSL_NG_H_ +#if 0 + #include <cstdint> #include <atomic> #include <memory> @@ -173,4 +175,6 @@ using SocketTcp::recv; }; +#endif + #endif // !_SOCKET_SSL_NG_H_
--- a/C++/modules/Socket/SocketTcp.cpp Fri Jun 19 13:56:12 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -/* - * SocketTcp.cpp -- portable C++ socket wrappers - * - * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "SocketAddress.h" -#include "SocketTcp.h" - -void SocketTcp::listen(int max) -{ - if (::listen(m_handle, max) == Error) { - throw SocketError(SocketError::System, "listen"); - } -} - -std::unique_ptr<SocketTcp> SocketTcp::accept() -{ - std::unique_ptr<SocketAddress> dummy; - - return accept(dummy); -} - -std::unique_ptr<SocketTcp> SocketTcp::accept(std::unique_ptr<SocketAddress> &info) -{ - Socket::Handle handle; - - // Store the information - sockaddr_storage address; - socklen_t addrlen; - - addrlen = sizeof (sockaddr_storage); - handle = ::accept(m_handle, reinterpret_cast<sockaddr *>(&address), &addrlen); - - if (handle == Invalid) { -#if defined(_WIN32) - int error = WSAGetLastError(); - - if (error == WSAEWOULDBLOCK) { - throw SocketError(SocketError::WouldBlockRead, "accept", error); - } - - throw SocketError(SocketError::System, "accept", error); -#else - if (errno == EAGAIN || errno == EWOULDBLOCK) { - throw SocketError(SocketError::WouldBlockRead, "accept"); - } - - throw SocketError(SocketError::System, "accept"); -#endif - } - - info = SocketAddress::decode(address, addrlen); - - return std::make_unique<SocketTcp>(handle); -} - -void SocketTcp::connect(const std::unique_ptr<SocketAddress> &address) -{ - if (m_state == SocketState::Connected) { - return; - } - - auto &sa = address->address(); - auto addrlen = address->length(); - - if (::connect(m_handle, reinterpret_cast<const sockaddr *>(&sa), addrlen) == Error) { - /* - * Determine if the error comes from a non-blocking connect that cannot be - * accomplished yet. - */ -#if defined(_WIN32) - int error = WSAGetLastError(); - - if (error == WSAEWOULDBLOCK) { - throw SocketError(SocketError::WouldBlockWrite, "connect", error); - } - - throw SocketError(SocketError::System, "connect", error); -#else - if (errno == EINPROGRESS) { - throw SocketError(SocketError::WouldBlockWrite, "connect"); - } - - throw SocketError(SocketError::System, "connect"); -#endif - } - - m_state = SocketState::Connected; -} - -unsigned SocketTcp::recv(void *data, unsigned dataLen) -{ - int nbread; - - nbread = ::recv(m_handle, (Socket::Arg)data, dataLen, 0); - if (nbread == Error) { -#if defined(_WIN32) - int error = WSAGetLastError(); - - if (error == WSAEWOULDBLOCK) { - throw SocketError(SocketError::WouldBlockRead, "recv", error); - } - - throw SocketError(SocketError::System, "recv", error); -#else - if (errno == EAGAIN || errno == EWOULDBLOCK) { - throw SocketError(SocketError::WouldBlockRead, "recv"); - } - - throw SocketError(SocketError::System, "recv"); -#endif - } else if (nbread == 0) { - m_state = SocketState::Closed; - } - - return (unsigned)nbread; -} - -unsigned SocketTcp::send(const void *data, unsigned length) -{ - int nbsent; - - nbsent = ::send(m_handle, (Socket::ConstArg)data, length, 0); - if (nbsent == Error) { -#if defined(_WIN32) - int error = WSAGetLastError(); - - if (error == WSAEWOULDBLOCK) { - throw SocketError(SocketError::WouldBlockWrite, "send", error); - } - - throw SocketError(SocketError::System, "send", error); -#else - if (errno == EAGAIN || errno == EWOULDBLOCK) { - throw SocketError(SocketError::WouldBlockWrite, "send"); - } - - throw SocketError(SocketError::System, "send"); -#endif - } - - return (unsigned)nbsent; -}
--- a/C++/modules/Socket/SocketTcp.h Fri Jun 19 13:56:12 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/* - * SocketTcp.h -- portable C++ socket wrappers - * - * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SOCKET_TCP_NG_H_ -#define _SOCKET_TCP_NG_H_ - -#include <memory> - -#include "Socket.h" - -/** - * @class SocketTcp - * @brief End-user class for TCP sockets - */ -class SocketTcp : public Socket { -public: - /** - * Inherited constructors. - */ - using Socket::Socket; - - /** - * Construct a standard TCP socket. The type is automatically - * set to SOCK_STREAM. - * - * @param domain the domain - * @param protocol the protocol - * @throw SocketError on error - */ - inline SocketTcp(int domain, int protocol) - : Socket(domain, SOCK_STREAM, protocol) - { - } - - /** - * Listen for pending connection. - * - * @param max the maximum number - */ - virtual void listen(int max = 128); - - /** - * Accept a clear TCP socket without its address - * - * @return the socket - * @throw SocketError on error - */ - std::unique_ptr<SocketTcp> accept(); - - /** - * Accept a clear TCP socket. - * - * @param info the client information - * @return the socket - * @throw SocketError on error - */ - virtual std::unique_ptr<SocketTcp> accept(std::unique_ptr<SocketAddress> &info); - - /** - * Connect to an end point. - * - * @param address the address - * @throw SocketError on error - */ - virtual void connect(const std::unique_ptr<SocketAddress> &address); - - /** - * Receive some data. - * - * @param data the destination buffer - * @param length the buffer length - * @throw SocketError on error - */ - virtual unsigned recv(void *data, unsigned length); - - /** - * Overloaded function. - * - * @param count the number of bytes to receive - * @return the string - * @throw SocketError on error - */ - inline std::string recv(unsigned count) - { - std::string result; - - result.resize(count); - auto n = recv(const_cast<char *>(result.data()), count); - result.resize(n); - - return result; - } - - /** - * Send some data. - * - * @param data the data to send - * @param length the data length - */ - virtual unsigned send(const void *data, unsigned length); - - /** - * Overloaded function. - * - * @param data the string to send - * @return the number of bytes sent - * @throw SocketError on error - */ - inline unsigned send(const std::string &data) - { - return send(data.c_str(), data.size()); - } -}; - -#endif // !_SOCKET_TCP_NG_H_
--- a/C++/modules/Socket/SocketUdp.cpp Fri Jun 19 13:56:12 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * SocketUdp.cpp -- portable C++ socket wrappers - * - * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "SocketAddress.h" -#include "SocketUdp.h" - -SocketUdp::SocketUdp(int domain, int protocol) - : Socket(domain, SOCK_DGRAM, protocol) -{ -} - -unsigned SocketUdp::recvfrom(void *data, unsigned length, std::unique_ptr<SocketAddress> &info) -{ - int nbread; - - // Store information - sockaddr_storage address; - socklen_t addrlen; - - addrlen = sizeof (struct sockaddr_storage); - nbread = ::recvfrom(m_handle, (Socket::Arg)data, length, 0, (sockaddr *)&address, &addrlen); - - info = SocketAddress::decode(address, addrlen); - - if (nbread == Error) { -#if defined(_WIN32) - int error = WSAGetLastError(); - - if (error == WSAEWOULDBLOCK) { - throw SocketError(SocketError::WouldBlockRead, "recvfrom", error); - } - - throw SocketError(SocketError::System, "recvfrom", error); -#else - if (errno == EAGAIN || errno == EWOULDBLOCK) { - throw SocketError(SocketError::WouldBlockRead, "recvfrom"); - } - - throw SocketError(SocketError::System, "recvfrom"); -#endif - } - - return (unsigned)nbread; -} - -unsigned SocketUdp::sendto(const void *data, unsigned length, const std::unique_ptr<SocketAddress> &info) -{ - int nbsent; - - nbsent = ::sendto(m_handle, (Socket::ConstArg)data, length, 0, (const sockaddr *)&info->address(), info->length()); - if (nbsent == Error) { -#if defined(_WIN32) - int error = WSAGetLastError(); - - if (error == WSAEWOULDBLOCK) { - throw SocketError(SocketError::WouldBlockWrite, "sendto", error); - } - - throw SocketError(SocketError::System, "sendto", error); -#else - if (errno == EAGAIN || errno == EWOULDBLOCK) { - throw SocketError(SocketError::WouldBlockWrite, "sendto"); - } - - throw SocketError(SocketError::System, "sendto"); -#endif - } - - return (unsigned)nbsent; -}
--- a/C++/modules/Socket/SocketUdp.h Fri Jun 19 13:56:12 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* - * SocketUdp.h -- portable C++ socket wrappers - * - * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SOCKET_UDP_NG_H_ -#define _SOCKET_UDP_NG_H_ - -#include "Socket.h" - -/** - * @class SocketUdp - * @brief UDP implementation for sockets - */ -class SocketUdp : public Socket { -public: - /** - * Construct a UDP socket. The type is automatically set to SOCK_DGRAM. - * - * @param domain the domain (e.g AF_INET) - * @param protocol the protocol (usually 0) - */ - SocketUdp(int domain, int protocol); - - /** - * Overloaded function. - * - * @param data the data - * @param address the address - * @return the number of bytes sent - * @throw SocketError on error - */ - inline unsigned sendto(const std::string &data, const std::unique_ptr<SocketAddress> &address) - { - return sendto(data.c_str(), data.length(), address); - } - - /** - * Overloaded function. - * - * @param data the data - * @param info the client information - * @return the string - * @throw SocketError on error - */ - inline std::string recvfrom(unsigned count, std::unique_ptr<SocketAddress> &info) - { - std::string result; - - result.resize(count); - auto n = recvfrom(const_cast<char *>(result.data()), count, info); - result.resize(n); - - return result; - } - - /** - * Receive data from an end point. - * - * @param data the destination buffer - * @param length the buffer length - * @param info the client information - * @return the number of bytes received - * @throw SocketError on error - */ - virtual unsigned recvfrom(void *data, unsigned length, std::unique_ptr<SocketAddress> &info); - - /** - * Send data to an end point. - * - * @param data the buffer - * @param length the buffer length - * @param address the client address - * @return the number of bytes sent - * @throw SocketError on error - */ - virtual unsigned sendto(const void *data, unsigned length, const std::unique_ptr<SocketAddress> &address); -}; - -#endif // !_SOCKET_UDP_NG_H_
--- a/C++/tests/Socket/main.cpp Fri Jun 19 13:56:12 2015 +0200 +++ b/C++/tests/Socket/main.cpp Tue Jun 23 14:06:37 2015 +0200 @@ -40,8 +40,8 @@ class TcpServerTest : public testing::Test { protected: - SocketTcp m_server{AF_INET, 0}; - SocketTcp m_client{AF_INET, 0}; + SocketTcp<Ipv4> m_server{AF_INET, 0}; + SocketTcp<Ipv4> m_client{AF_INET, 0}; std::thread m_tserver; std::thread m_tclient; @@ -64,7 +64,7 @@ TEST_F(TcpServerTest, connect) { m_tserver = std::thread([this] () { - m_server.bind(std::make_unique<Internet>("*", 16000, AF_INET)); + m_server.bind(Ipv4{"*", 16000}); ASSERT_EQ(SocketState::Bound, m_server.state()); @@ -76,7 +76,7 @@ std::this_thread::sleep_for(100ms); m_tclient = std::thread([this] () { - m_client.connect(std::make_unique<Internet>("127.0.0.1", 16000, AF_INET)); + m_client.connect(Ipv4{"127.0.0.1", 16000}); ASSERT_EQ(SocketState::Connected, m_client.state()); @@ -87,21 +87,21 @@ TEST_F(TcpServerTest, io) { m_tserver = std::thread([this] () { - m_server.bind(std::make_unique<Internet>("*", 16000, AF_INET)); + m_server.bind(Ipv4{"*", 16000}); m_server.listen(); auto client = m_server.accept(); - auto msg = client->recv(512); + auto msg = client.recv(512); ASSERT_EQ("hello world", msg); - client->send(msg); + client.send(msg); }); std::this_thread::sleep_for(100ms); m_tclient = std::thread([this] () { - m_client.connect(std::make_unique<Internet>("127.0.0.1", 16000, AF_INET)); + m_client.connect(Ipv4{"127.0.0.1", 16000}); m_client.send("hello world"); ASSERT_EQ("hello world", m_client.recv(512)); @@ -114,8 +114,8 @@ class UdpServerTest : public testing::Test { protected: - SocketUdp m_server{AF_INET, 0}; - SocketUdp m_client{AF_INET, 0}; + SocketUdp<Ipv4> m_server{AF_INET, 0}; + SocketUdp<Ipv4> m_client{AF_INET, 0}; std::thread m_tserver; std::thread m_tclient; @@ -138,7 +138,7 @@ TEST_F(UdpServerTest, io) { m_tserver = std::thread([this] () { - std::unique_ptr<SocketAddress> info = std::make_unique<Internet>("*", 16000, AF_INET); + Ipv4 info{"*", 16000}; m_server.bind(info); auto msg = m_server.recvfrom(512, info); @@ -152,7 +152,7 @@ std::this_thread::sleep_for(100ms); m_tclient = std::thread([this] () { - std::unique_ptr<SocketAddress> info = std::make_unique<Internet>("127.0.0.1", 16000, AF_INET); + Ipv4 info{"127.0.0.1", 16000}; m_client.sendto("hello world", info); @@ -172,33 +172,40 @@ bool m_added{false}; int m_flags{0}; - inline void set(const SocketTable &, const std::shared_ptr<Socket> &sc, int flags, bool add) noexcept + inline void set(const SocketTable &, SocketAbstract &sc, int flags, bool add) noexcept { m_callcount ++; m_added = add; m_flags |= flags; } - inline void unset(const SocketTable &, const std::shared_ptr<Socket> &, int, bool) noexcept {} + inline void unset(const SocketTable &, SocketAbstract &, int, bool) noexcept + { + } + std::vector<SocketStatus> wait(const SocketTable &table, int ms) {} }; class TestBackendSetFail { public: - inline void set(const SocketTable &, const std::shared_ptr<Socket> &, int, bool) + inline void set(const SocketTable &, SocketAbstract &, int, bool) { throw "fail"; } - inline void unset(const SocketTable &, const std::shared_ptr<Socket> &, int, bool) noexcept {} + inline void unset(const SocketTable &, const SocketAbstract &, int, bool) noexcept + { + } + std::vector<SocketStatus> wait(const SocketTable &table, int ms) {} }; TEST(ListenerSet, initialAdd) { SocketListenerBase<TestBackendSet> listener; + SocketAbstract s{0}; - listener.set(std::make_shared<Socket>(0), SocketListener::Read); + listener.set(s, SocketListener::Read); ASSERT_EQ(1U, listener.size()); ASSERT_EQ(1, listener.backend().m_callcount); @@ -209,10 +216,10 @@ TEST(ListenerSet, readThenWrite) { SocketListenerBase<TestBackendSet> listener; - std::shared_ptr<Socket> sc = std::make_shared<Socket>(0); + SocketAbstract s{0}; - listener.set(sc, SocketListener::Read); - listener.set(sc, SocketListener::Write); + listener.set(s, SocketListener::Read); + listener.set(s, SocketListener::Write); ASSERT_EQ(1U, listener.size()); ASSERT_EQ(2, listener.backend().m_callcount); @@ -223,9 +230,9 @@ TEST(ListenerSet, allOneShot) { SocketListenerBase<TestBackendSet> listener; - std::shared_ptr<Socket> sc = std::make_shared<Socket>(0); + SocketAbstract s{0}; - listener.set(sc, SocketListener::Read | SocketListener::Write); + listener.set(s, SocketListener::Read | SocketListener::Write); ASSERT_EQ(1U, listener.size()); ASSERT_EQ(1, listener.backend().m_callcount); @@ -236,10 +243,10 @@ TEST(ListenerSet, readTwice) { SocketListenerBase<TestBackendSet> listener; - std::shared_ptr<Socket> sc = std::make_shared<Socket>(0); + SocketAbstract s{0}; - listener.set(sc, SocketListener::Read); - listener.set(sc, SocketListener::Read); + listener.set(s, SocketListener::Read); + listener.set(s, SocketListener::Read); ASSERT_EQ(1U, listener.size()); ASSERT_EQ(1, listener.backend().m_callcount); @@ -250,9 +257,10 @@ TEST(ListenerSet, failure) { SocketListenerBase<TestBackendSetFail> listener; + SocketAbstract s{0}; try { - listener.set(std::make_shared<Socket>(0), SocketListener::Read); + listener.set(s, SocketListener::Read); FAIL() << "exception expected"; } catch (...) { } @@ -271,41 +279,49 @@ int m_flags{0}; bool m_removal{false}; - inline void set(const SocketTable &, const std::shared_ptr<Socket> &, int flags, bool) noexcept + inline void set(const SocketTable &, SocketAbstract &, int flags, bool) noexcept { m_isset = true; m_flags |= flags; } - inline void unset(const SocketTable &, const std::shared_ptr<Socket> &, int flags, bool remove) noexcept + inline void unset(const SocketTable &, SocketAbstract &, int flags, bool remove) noexcept { m_isunset = true; m_flags &= ~(flags); m_removal = remove; } - std::vector<SocketStatus> wait(const SocketTable &table, int ms) {} + std::vector<SocketStatus> wait(const SocketTable &, int) noexcept + { + return {}; + } }; class TestBackendUnsetFail { public: - inline void set(const SocketTable &, const std::shared_ptr<Socket> &, int, bool) noexcept {} + inline void set(const SocketTable &, SocketAbstract &, int, bool) noexcept + { + } - inline void unset(const SocketTable &, const std::shared_ptr<Socket> &, int, bool) + inline void unset(const SocketTable &, SocketAbstract &, int, bool) { throw "fail"; } - std::vector<SocketStatus> wait(const SocketTable &table, int ms) {} + std::vector<SocketStatus> wait(const SocketTable &, int) + { + return {}; + } }; TEST(ListenerUnsetRemove, unset) { SocketListenerBase<TestBackendUnset> listener; - std::shared_ptr<Socket> sc = std::make_shared<Socket>(0); + SocketAbstract s{0}; - listener.set(sc, SocketListener::Read); - listener.unset(sc, SocketListener::Read); + listener.set(s, SocketListener::Read); + listener.unset(s, SocketListener::Read); ASSERT_EQ(0U, listener.size()); ASSERT_TRUE(listener.backend().m_isset); @@ -317,10 +333,10 @@ TEST(ListenerUnsetRemove, unsetOne) { SocketListenerBase<TestBackendUnset> listener; - std::shared_ptr<Socket> sc = std::make_shared<Socket>(0); + SocketAbstract s{0}; - listener.set(sc, SocketListener::Read | SocketListener::Write); - listener.unset(sc, SocketListener::Read); + listener.set(s, SocketListener::Read | SocketListener::Write); + listener.unset(s, SocketListener::Read); ASSERT_EQ(1U, listener.size()); ASSERT_TRUE(listener.backend().m_isset); @@ -332,11 +348,11 @@ TEST(ListenerUnsetRemove, unsetAll) { SocketListenerBase<TestBackendUnset> listener; - std::shared_ptr<Socket> sc = std::make_shared<Socket>(0); + SocketAbstract s{0}; - listener.set(sc, SocketListener::Read | SocketListener::Write); - listener.unset(sc, SocketListener::Read); - listener.unset(sc, SocketListener::Write); + listener.set(s, SocketListener::Read | SocketListener::Write); + listener.unset(s, SocketListener::Read); + listener.unset(s, SocketListener::Write); ASSERT_EQ(0U, listener.size()); ASSERT_TRUE(listener.backend().m_isset); @@ -348,10 +364,10 @@ TEST(ListenerUnsetRemove, remove) { SocketListenerBase<TestBackendUnset> listener; - std::shared_ptr<Socket> sc = std::make_shared<Socket>(0); + SocketAbstract s{0}; - listener.set(sc, SocketListener::Read | SocketListener::Write); - listener.remove(sc); + listener.set(s, SocketListener::Read | SocketListener::Write); + listener.remove(s); ASSERT_EQ(0U, listener.size()); ASSERT_TRUE(listener.backend().m_isset); @@ -363,12 +379,12 @@ TEST(ListenerUnsetRemove, failure) { SocketListenerBase<TestBackendUnsetFail> listener; - std::shared_ptr<Socket> sc = std::make_shared<Socket>(0); + SocketAbstract s{0}; - listener.set(sc, SocketListener::Read | SocketListener::Write); + listener.set(s, SocketListener::Read | SocketListener::Write); try { - listener.remove(sc); + listener.remove(s); FAIL() << "exception expected"; } catch (...) { } @@ -384,20 +400,20 @@ class ListenerTest : public testing::Test { protected: SocketListenerBase<backend::Select> m_listener; - std::shared_ptr<SocketTcp> m_masterTcp; - std::shared_ptr<SocketTcp> m_clientTcp; + SocketTcp<Ipv4> m_masterTcp; + SocketTcp<Ipv4> m_clientTcp; std::thread m_tserver; std::thread m_tclient; public: ListenerTest() - : m_masterTcp{std::make_shared<SocketTcp>(AF_INET, 0)} - , m_clientTcp{std::make_shared<SocketTcp>(AF_INET, 0)} + : m_masterTcp{AF_INET, 0} + , m_clientTcp{AF_INET, 0} { - m_masterTcp->set(SOL_SOCKET, SO_REUSEADDR, 1); - m_masterTcp->bind(std::make_unique<Internet>("*", 16000, AF_INET)); - m_masterTcp->listen(); + m_masterTcp.set(SOL_SOCKET, SO_REUSEADDR, 1); + m_masterTcp.bind(Ipv4{"*", 16000}); + m_masterTcp.listen(); } ~ListenerTest() @@ -417,8 +433,8 @@ try { m_listener.set(m_masterTcp, SocketListener::Read); m_listener.wait(); - m_masterTcp->accept(); - m_masterTcp->close(); + m_masterTcp.accept(); + m_masterTcp.close(); } catch (const std::exception &ex) { FAIL() << ex.what(); } @@ -427,7 +443,7 @@ std::this_thread::sleep_for(100ms); m_tclient = std::thread([this] () { - m_clientTcp->connect(std::make_unique<Internet>("127.0.0.1", 16000, AF_INET)); + m_clientTcp.connect(Ipv4{"127.0.0.1", 16000}); }); } @@ -438,9 +454,9 @@ m_listener.set(m_masterTcp, SocketListener::Read); m_listener.wait(); - auto sc = m_masterTcp->accept(); + auto sc = m_masterTcp.accept(); - ASSERT_EQ("hello", sc->recv(512)); + ASSERT_EQ("hello", sc.recv(512)); } catch (const std::exception &ex) { FAIL() << ex.what(); } @@ -449,8 +465,8 @@ std::this_thread::sleep_for(100ms); m_tclient = std::thread([this] () { - m_clientTcp->connect(std::make_unique<Internet>("127.0.0.1", 16000, AF_INET)); - m_clientTcp->send("hello"); + m_clientTcp.connect(Ipv4{"127.0.0.1", 16000}); + m_clientTcp.send("hello"); }); } @@ -460,8 +476,8 @@ class NonBlockingConnectTest : public testing::Test { protected: - SocketTcp m_server{AF_INET, 0}; - SocketTcp m_client{AF_INET, 0}; + SocketTcp<Ipv4> m_server{AF_INET, 0}; + SocketTcp<Ipv4> m_client{AF_INET, 0}; std::thread m_tserver; std::thread m_tclient; @@ -487,8 +503,8 @@ class TcpAcceptTest : public testing::Test { protected: - SocketTcp m_server{AF_INET, 0}; - SocketTcp m_client{AF_INET, 0}; + SocketTcp<Ipv4> m_server{AF_INET, 0}; + SocketTcp<Ipv4> m_client{AF_INET, 0}; std::thread m_tserver; std::thread m_tclient; @@ -497,7 +513,7 @@ TcpAcceptTest() { m_server.set(SOL_SOCKET, SO_REUSEADDR, 1); - m_server.bind(std::make_unique<Internet>("*", 16000, AF_INET)); + m_server.bind(Ipv4{"*", 16000}); m_server.listen(); } @@ -516,8 +532,8 @@ class TcpRecvTest : public testing::Test { protected: - SocketTcp m_server{AF_INET, 0}; - SocketTcp m_client{AF_INET, 0}; + SocketTcp<Ipv4> m_server{AF_INET, 0}; + SocketTcp<Ipv4> m_client{AF_INET, 0}; std::thread m_tserver; std::thread m_tclient; @@ -526,7 +542,7 @@ TcpRecvTest() { m_server.set(SOL_SOCKET, SO_REUSEADDR, 1); - m_server.bind(std::make_unique<Internet>("*", 16000, AF_INET)); + m_server.bind(Ipv4{"*", 16000}); m_server.listen(); } @@ -544,13 +560,13 @@ m_tserver = std::thread([this] () { auto client = m_server.accept(); - ASSERT_EQ("hello", client->recv(32)); + ASSERT_EQ("hello", client.recv(32)); }); std::this_thread::sleep_for(100ms); m_tclient = std::thread([this] () { - m_client.connect(std::make_unique<Internet>("127.0.0.1", 16000, AF_INET)); + m_client.connect(Ipv4{"127.0.0.1", 16000}); m_client.send("hello"); m_client.close(); }); @@ -560,6 +576,8 @@ * Socket SSL * -------------------------------------------------------- */ +#if 0 + class SslTest : public testing::Test { protected: SocketSsl client{AF_INET, 0}; @@ -592,6 +610,8 @@ } } +#endif + int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv);
--- a/CMakeLists.txt Fri Jun 19 13:56:12 2015 +0200 +++ b/CMakeLists.txt Tue Jun 23 14:06:37 2015 +0200 @@ -363,10 +363,6 @@ ${code_SOURCE_DIR}/C++/modules/Socket/SocketListener.h ${code_SOURCE_DIR}/C++/modules/Socket/SocketSsl.cpp ${code_SOURCE_DIR}/C++/modules/Socket/SocketSsl.h - ${code_SOURCE_DIR}/C++/modules/Socket/SocketTcp.cpp - ${code_SOURCE_DIR}/C++/modules/Socket/SocketTcp.h - ${code_SOURCE_DIR}/C++/modules/Socket/SocketUdp.cpp - ${code_SOURCE_DIR}/C++/modules/Socket/SocketUdp.h ) endif ()