changeset 431:7f01d500460a

Sockets: begin of massive refactoring and redesign
author David Demelier <markand@malikania.fr>
date Wed, 21 Oct 2015 21:24:04 +0200
parents 625f5d64b093
children da92b98de599
files C++/modules/Socket/Socket.cpp C++/modules/Socket/Socket.h C++/modules/Socket/SocketAddress.h CMakeLists.txt
diffstat 4 files changed, 2 insertions(+), 1334 deletions(-) [+]
line wrap: on
line diff
--- a/C++/modules/Socket/Socket.cpp	Wed Oct 14 20:19:28 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-/*
- * Socket.cpp -- portable C++ socket wrappers
- *
- * Copyright (c) 2013-2015 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 <cstring>
-
-#include "Socket.h"
-#include "SocketAddress.h"
-
-/* --------------------------------------------------------
- * System dependent code
- * -------------------------------------------------------- */
-
-#if defined(_WIN32)
-const SocketAbstract::Handle SocketAbstract::Invalid{INVALID_SOCKET};
-const int SocketAbstract::Error{SOCKET_ERROR};
-#else
-const int SocketAbstract::Invalid{-1};
-const int SocketAbstract::Error{-1};
-#endif
-
-#if defined(_WIN32)
-
-std::string SocketAbstract::syserror(int errn)
-{
-	LPSTR str = nullptr;
-	std::string errmsg = "Unknown error";
-
-	FormatMessageA(
-		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-		NULL,
-		errn,
-		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-		(LPSTR)&str, 0, NULL);
-
-
-	if (str) {
-		errmsg = std::string(str);
-		LocalFree(str);
-	}
-
-	return errmsg;
-}
-
-#else
-
-std::string SocketAbstract::syserror(int errn)
-{
-	return strerror(errn);
-}
-
-#endif
-
-std::string SocketAbstract::syserror()
-{
-#if defined(_WIN32)
-	return syserror(WSAGetLastError());
-#else
-	return syserror(errno);
-#endif
-}
-
-/* --------------------------------------------------------
- * SocketError class
- * -------------------------------------------------------- */
-
-SocketError::SocketError(Code code, std::string function)
-	: 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{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)}
-{
-}
-
-/* --------------------------------------------------------
- * SocketAbstract class
- * -------------------------------------------------------- */
-
-#if defined(_WIN32)
-std::mutex SocketAbstract::s_mutex;
-std::atomic<bool> SocketAbstract::s_initialized{false};
-#endif
-
-SocketAbstract::SocketAbstract(int domain, int type, int protocol)
-{
-#if defined(_WIN32) && !defined(SOCKET_NO_WSA_INIT)
-	if (!s_initialized) {
-		initialize();
-	}
-#endif
-
-	m_handle = ::socket(domain, type, protocol);
-
-	if (m_handle == Invalid) {
-		throw SocketError{SocketError::System, "socket"};
-	}
-}
-
-SocketAbstract::SocketAbstract(SocketAbstract &&other) noexcept
-{
-	m_handle = other.m_handle;
-
-	// Invalidate other
-	other.m_handle = -1;
-}
-
-SocketAbstract::~SocketAbstract()
-{
-	close();
-}
-
-void SocketAbstract::close()
-{
-	if (m_handle != Invalid) {
-#if defined(_WIN32)
-		::closesocket(m_handle);
-#else
-		::close(m_handle);
-#endif
-		m_handle = Invalid;
-	}
-}
-
-void SocketAbstract::setBlockMode(bool block)
-{
-#if defined(O_NONBLOCK) && !defined(_WIN32)
-	int flags;
-
-	if ((flags = fcntl(m_handle, F_GETFL, 0)) == -1) {
-		flags = 0;
-	}
-
-	if (block) {
-		flags &= ~(O_NONBLOCK);
-	} else {
-		flags |= O_NONBLOCK;
-	}
-
-	if (fcntl(m_handle, F_SETFL, flags) == Error) {
-		throw SocketError{SocketError::System, "setBlockMode"};
-	}
-#else
-	unsigned long flags = (block) ? 0 : 1;
-
-	if (ioctlsocket(m_handle, FIONBIO, &flags) == Error) {
-		throw SocketError{SocketError::System, "setBlockMode"};
-	}
-#endif
-}
-
-SocketAbstract &SocketAbstract::operator=(SocketAbstract &&other) noexcept
-{
-	m_handle = other.m_handle;
-
-	// Invalidate other
-	other.m_handle = Invalid;
-
-	return *this;
-}
-
-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();
-}
-
-bool operator>=(const SocketAbstract &s1, const SocketAbstract &s2)
-{
-	return s1.handle() >= s2.handle();
-}
--- a/C++/modules/Socket/Socket.h	Wed Oct 14 20:19:28 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1048 +0,0 @@
-/*
- * Socket.h -- portable C++ socket wrappers
- *
- * Copyright (c) 2013-2015 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_NG_H_
-#define _SOCKET_NG_H_
-
-/**
- * @file Socket.h
- * @brief Portable socket abstraction
- *
- * User may set the following variables before compiling these files:
- *
- * - **SOCKET_NO_WSA_INIT**:(bool) Set to false if you don't want Socket class to
- * automatically calls WSAStartup() when creating sockets. Otherwise, you will need to call
- * SocketAbstract::init, SocketAbstract::finish yourself.
- *
- */
-
-#include <cstdlib>
-#include <cstring>
-#include <exception>
-#include <memory>
-#include <string>
-
-#if defined(_WIN32)
-#  include <atomic>
-#  include <cstdlib>
-#  include <mutex>
-
-#  include <WinSock2.h>
-#  include <WS2tcpip.h>
-#else
-#  include <cerrno>
-
-#  include <sys/ioctl.h>
-#  include <sys/socket.h>
-#  include <sys/types.h>
-
-#  include <arpa/inet.h>
-
-#  include <netinet/in.h>
-
-#  include <fcntl.h>
-#  include <netdb.h>
-#  include <unistd.h>
-#endif
-
-class SocketAddress;
-
-/* --------------------------------------------------------
- * Socket types and errors
- * -------------------------------------------------------- */
-
-/**
- * @class SocketError
- * @brief Base class for sockets error
- */
-class SocketError : public std::exception {
-public:
-	/**
-	 * @enum Code
-	 * @brief Which kind of error
-	 */
-	enum Code {
-		WouldBlockRead,		///!< The operation would block for reading
-		WouldBlockWrite,	///!< The operation would block for writing
-		Timeout,		///!< The action did timeout
-		System			///!< There is a system error
-	};
-
-private:
-	Code m_code;
-	std::string m_function;
-	std::string m_error;
-
-public:
-	/**
-	 * Constructor that use the last system error.
-	 *
-	 * @param code which kind of error
-	 * @param function the function name
-	 */
-	SocketError(Code code, std::string function);
-
-	/**
-	 * Constructor that use the system error set by the user.
-	 *
-	 * @param code which kind of error
-	 * @param function the function name
-	 * @param error the error
-	 */
-	SocketError(Code code, std::string function, int error);
-
-	/**
-	 * Constructor that set the error specified by the user.
-	 *
-	 * @param code which kind of error
-	 * @param function the function name
-	 * @param error the error
-	 */
-	SocketError(Code code, std::string function, std::string error);
-
-	/**
-	 * Get which function has triggered the error.
-	 *
-	 * @return the function name (e.g connect)
-	 */
-	inline const std::string &function() const noexcept
-	{
-		return m_function;
-	}
-
-	/**
-	 * The error code.
-	 *
-	 * @return the code
-	 */
-	inline Code code() const noexcept
-	{
-		return m_code;
-	}
-
-	/**
-	 * Get the error (only the error content).
-	 *
-	 * @return the error
-	 */
-	const char *what() const noexcept
-	{
-		return m_error.c_str();
-	}
-};
-
-/* --------------------------------------------------------
- * Generic base sockets
- * -------------------------------------------------------- */
-
-/**
- * @class SocketAbstract
- * @brief Base socket class for socket operations
- */
-class SocketAbstract {
-public:
-	/* {{{ Portable types */
-
-	/*
-	 * The following types are defined differently between Unix
-	 * and Windows.
-	 */
-#if defined(_WIN32)
-	/**
-	 * Socket type, SOCKET.
-	 */
-	using Handle	= SOCKET;
-
-	/**
-	 * Argument to pass to set.
-	 */
-	using ConstArg	= const char *;
-
-	/**
-	 * Argument to pass to get.
-	 */
-	using Arg	= char *;
-#else
-	/**
-	 * Socket type, int.
-	 */
-	using Handle	= int;
-
-	/**
-	 * Argument to pass to set.
-	 */
-	using ConstArg	= const void *;
-
-	/**
-	 * Argument to pass to get.
-	 */
-	using Arg	= void *;
-#endif
-
-	/* }}} */
-
-	/* {{{ Portable constants */
-
-	/*
-	 * The following constants are defined differently from Unix
-	 * to Windows.
-	 */
-#if defined(_WIN32)
-	/**
-	 * Socket creation failure or invalidation.
-	 */
-	static const Handle Invalid;
-
-	/**
-	 * Socket operation failure.
-	 */
-	static const int Error;
-#else
-	/**
-	 * Socket creation failure or invalidation.
-	 */
-	static const int Invalid;
-
-	/**
-	 * Socket operation failure.
-	 */
-	static const int Error;
-#endif
-
-	/* }}} */
-
-	/* {{{ Portable initialization */
-
-	/*
-	 * Initialization stuff.
-	 *
-	 * The function init and finish are threadsafe.
-	 */
-#if defined(_WIN32)
-private:
-	static std::mutex s_mutex;
-	static std::atomic<bool> s_initialized;
-
-public:
-	/**
-	 * Calls WSACleanup.
-	 */
-	static inline void finish() noexcept
-	{
-		WSACleanup();
-	}
-
-	/**
-	 * Initialize using WSAStartup.
-	 */
-	static inline void initialize() noexcept
-	{
-		std::lock_guard<std::mutex> lock(s_mutex);
-
-		if (!s_initialized) {
-			s_initialized = true;
-
-			WSADATA wsa;
-			WSAStartup(MAKEWORD(2, 2), &wsa);
-
-			/*
-			 * If SOCKET_WSA_NO_INIT is not set then the user
-			 * must also call finish himself.
-			 */
-#if !defined(SOCKET_WSA_NO_INIT)
-			atexit(finish);
-#endif
-		}
-	}
-#else
-public:
-	/**
-	 * no-op.
-	 */
-	static inline void initialize() noexcept {}
-
-	/**
-	 * no-op.
-	 */
-	static inline void finish() noexcept {}
-#endif
-
-	/* }}} */
-
-protected:
-	Handle m_handle{Invalid};			//!< The native handle
-
-public:
-	/**
-	 * Get the last socket system error. The error is set from errno or from
-	 * WSAGetLastError on Windows.
-	 *
-	 * @return a string message
-	 */
-	static std::string syserror();
-
-	/**
-	 * Get the last system error.
-	 *
-	 * @param errn the error number (errno or WSAGetLastError)
-	 * @return the error
-	 */
-	static std::string syserror(int errn);
-
-	/**
-	 * This create an invalid socket.
-	 */	
-	inline SocketAbstract() noexcept
-		: m_handle{Invalid}
-	{
-	}
-
-	/**
-	 * Construct a socket with an already created descriptor.
-	 *
-	 * @param handle the native descriptor
-	 */
-	explicit inline SocketAbstract(Handle handle) noexcept
-		: m_handle{handle}
-	{
-	}
-
-	/**
-	 * Create a socket handle.
-	 *
-	 * @param domain the domain AF_*
-	 * @param type the type SOCK_*
-	 * @param protocol the protocol
-	 * @throw SocketError on failures
-	 */
-	SocketAbstract(int domain, int type, int protocol);
-
-	/**
-	 * Copy constructor deleted.
-	 */
-	SocketAbstract(const SocketAbstract &) = delete;
-
-	/**
-	 * Transfer ownership from other to this.
-	 *
-	 * @param other the other socket
-	 */
-	SocketAbstract(SocketAbstract &&other) noexcept;
-
-	/**
-	 * Default destructor.
-	 */
-	virtual ~SocketAbstract();
-
-	/**
-	 * Set an option for the socket.
-	 *
-	 * @param level the setting level
-	 * @param name the name
-	 * @param arg the value
-	 * @throw SocketError on error
-	 */
-	template <typename Argument>
-	inline void set(int level, int name, const Argument &arg)
-	{
-#if defined(_WIN32)
-		if (setsockopt(m_handle, level, name, (SocketAbstract::ConstArg)&arg, sizeof (arg)) == Error)
-#else
-		if (setsockopt(m_handle, level, name, (SocketAbstract::ConstArg)&arg, sizeof (arg)) < 0)
-#endif
-			throw SocketError{SocketError::System, "set"};
-	}
-
-	/**
-	 * Get an option for the socket.
-	 *
-	 * @param level the setting level
-	 * @param name the name
-	 * @throw SocketError on error
-	 */
-	template <typename Argument>
-	inline Argument get(int level, int name)
-	{
-		Argument desired, result{};
-		socklen_t size = sizeof (result);
-
-#if defined(_WIN32)
-		if (getsockopt(m_handle, level, name, (SocketAbstract::Arg)&desired, &size) == Error)
-#else
-		if (getsockopt(m_handle, level, name, (SocketAbstract::Arg)&desired, &size) < 0)
-#endif
-			throw SocketError{SocketError::System, "get"};
-
-		std::memcpy(&result, &desired, size);
-
-		return result;
-	}
-
-	/**
-	 * Get the native handle.
-	 *
-	 * @return the handle
-	 * @warning Not portable
-	 */
-	inline Handle handle() const noexcept
-	{
-		return m_handle;
-	}
-
-	/**
-	 * Set the blocking mode, if set to false, the socket will be marked
-	 * **non-blocking**.
-	 *
-	 * @param block set to false to mark **non-blocking**
-	 * @throw SocketError on any error
-	 */
-	void setBlockMode(bool block);
-
-	/**
-	 * Close the socket.
-	 *
-	 * Automatically called from the destructor.
-	 */
-	virtual void close();
-
-	/**
-	 * Assignment operator forbidden.
-	 *
-	 * @return *this
-	 */
-	SocketAbstract &operator=(const SocketAbstract &) = delete;
-
-	/**
-	 * Transfer ownership from other to this. The other socket is left
-	 * invalid and will not be closed.
-	 *
-	 * @param other the other socket
-	 * @return this
-	 */
-	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;
-
-	/**
-	 * Default constructor.
-	 */
-	Socket() = default;
-
-	/**
-	 * 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"};
-		}
-	}
-
-	/**
-	 * 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> {
-protected:
-	/**
-	 * Do standard accept.
-	 *
-	 * @param info the address
-	 * @return the connected handle
-	 * @throw SocketError on error
-	 */
-	SocketAbstract::Handle standardAccept(Address &info);
-
-	/**
-	 * Do standard connect.
-	 *
-	 * @param info the address
-	 * @throw SocketError on error
-	 */
-	void standardConnect(const Address &info);
-
-public:
-	/**
-	 * Inherited constructors.
-	 */
-	using Socket<Address>::Socket;
-
-	/**
-	 * Default constructor.
-	 */
-	SocketAbstractTcp() = default;
-
-	/**
-	 * 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());
-	}
-};
-
-template <typename Address>
-SocketAbstract::Handle SocketAbstractTcp<Address>::standardAccept(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};
-	return handle;
-}
-
-template <typename Address>
-void SocketAbstractTcp<Address>::standardConnect(const Address &address)
-{
-	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
-	}
-}
-
-/**
- * @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;
-
-	/**
-	 * Default constructor.
-	 */
-	SocketTcp() = default;
-
-	/**
-	 * Connect to an end point.
-	 *
-	 * @param address the address
-	 * @throw SocketError on error
-	 */
-	inline void connect(const Address &address)
-	{
-		SocketAbstractTcp<Address>::standardConnect(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
-	 */
-	inline SocketTcp accept(Address &info)
-	{
-		return SocketTcp{SocketAbstractTcp<Address>::standardAccept(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>
-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
-	}
-
-	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);
-}
-
-/* --------------------------------------------------------
- * 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;
-
-	/**
-	 * Default constructor.
-	 */
-	SocketAbstractUdp() = default;
-
-	/**
-	 * 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 count the maximum number of bytes to receive
-	 * @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;
-
-	/**
-	 * Default constructor.
-	 */
-	SocketUdp() = default;
-
-	/**
-	 * @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.
- *
- * @param s1 the first socket
- * @param s2 the second socket
- * @return true if they equals
- */
-bool operator==(const SocketAbstract &s1, const SocketAbstract &s2);
-
-/**
- * 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 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.h	Wed Oct 14 20:19:28 2015 +0200
+++ b/C++/modules/Socket/SocketAddress.h	Wed Oct 21 21:24:04 2015 +0200
@@ -278,68 +278,6 @@
 	}
 };
 
-#if !defined(_WIN32)
-
-/**
- * @class Unix
- * @brief unix family sockets
- *
- * Create an address to a specific path. Only available on Unix.
- */
-class Unix : public SocketAddressAbstract {
-private:
-	sockaddr_un m_sun;
-	std::string m_path;
-
-public:
-	/**
-	 * Default constructor.
-	 */
-	Unix() = default;
-
-	/**
-	 * Construct an address to a path.
-	 *
-	 * @param path the path
-	 * @param rm remove the file before (default: false)
-	 */
-	Unix(std::string path, bool rm = false);
-
-	/**
-	 * Construct an unix address from a storage address.
-	 *
-	 * @param ss the storage
-	 * @param length the length
-	 */
-	Unix(const sockaddr_storage &ss, socklen_t length);
-
-	/**
-	 * @copydoc SocketAddress::address
-	 */
-	inline const sockaddr &address() const noexcept override
-	{
-		return reinterpret_cast<const sockaddr &>(m_sun);
-	}
-
-	/**
-	 * @copydoc SocketAddress::length
-	 */
-	inline socklen_t length() const noexcept override
-	{
-#if defined(SOCKET_HAVE_SUN_LEN)
-		return SUN_LEN(&m_sun);
-#else
-		return sizeof (m_sun);
-#endif
-	}
-
-	/**
-	 * @copydoc SocketAddress::info
-	 */
-	SocketAddressInfo info() const;
-};
-
-#endif // !_WIN32
 
 } // !address
 
--- a/CMakeLists.txt	Wed Oct 14 20:19:28 2015 +0200
+++ b/CMakeLists.txt	Wed Oct 21 21:24:04 2015 +0200
@@ -314,14 +314,8 @@
 			${SOCKET_LIBRARIES}
 			${OPENSSL_LIBRARIES}
 		SOURCES
-			${code_SOURCE_DIR}/C++/modules/Socket/SocketAddress.cpp
-			${code_SOURCE_DIR}/C++/modules/Socket/SocketAddress.h
-			${code_SOURCE_DIR}/C++/modules/Socket/Socket.cpp
-			${code_SOURCE_DIR}/C++/modules/Socket/Socket.h
-			${code_SOURCE_DIR}/C++/modules/Socket/SocketListener.cpp
-			${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/Sockets.cpp
+			${code_SOURCE_DIR}/C++/modules/Socket/Sockets.h
 	)
 endif ()