diff --git a/inc/netlib.hpp b/inc/netlib.hpp
index 0b039abf0ee4cf77e44854d29b5859f2dc02968a..7dfc681c11f0ea3694da36daa92e9f5a08cd2d08 100644
--- a/inc/netlib.hpp
+++ b/inc/netlib.hpp
@@ -7,5 +7,6 @@
 #include "tcplistener.hpp"
 #include "udpsocket.hpp"
 #include "resolver.hpp"
+#include "sockcopy.hpp"
 
 #endif // _NETLIB_HPP
\ No newline at end of file
diff --git a/inc/sockcopy.hpp b/inc/sockcopy.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..05899e6cc3f8db72650f3354e3c6cb229b54608b
--- /dev/null
+++ b/inc/sockcopy.hpp
@@ -0,0 +1,138 @@
+#ifndef _SOCKCOPY_HPP
+#define _SOCKCOPY_HPP
+
+#include "tcpstream.hpp"
+#include "tcplistener.hpp"
+#include "udpsocket.hpp"
+
+namespace netlib
+{
+
+
+/**
+ * @brief A special wrapper type that can be used to create
+ * automatically copyable socket objects. Without wrapping 
+ * socket objects in this class, an explicit clone function
+ * is needed to copy socket objects.
+ */
+template <class SockType>
+class SockCopy
+{
+private:
+    
+    /**
+     * @brief The wrapped socket instance.
+     */
+    SockType socket;
+
+public:
+
+    /**
+     * @brief Wrap the given socket so that it is copyable.
+     * 
+     * @note Autoclose should most likely be set to false on 
+     * the either one or both of the sockets to prevent accidentally 
+     * closing the socket.
+     * 
+     * @param socket The socket that will be wrapped.
+     */
+    SockCopy(const SockType &socket)
+        : socket{std::move(socket.clone())}
+    { }
+
+    /**
+     * @brief Wrap the given socket so that it is copyable.
+     * 
+     * @param socket The socket that will be wrapped.
+     */
+    SockCopy(SockType &&socket)
+        : socket{std::move(socket)}
+    { }
+
+    /**
+     * @brief Copy the given wrapped socket.
+     * 
+     * @note Autoclose should most likely be set to false on 
+     * the either one or both of the sockets to prevent accidentally 
+     * closing the socket.
+     * 
+     * @param socket The warpped socket to copy.
+     */
+    SockCopy(const SockCopy & other)
+        : SockCopy{std::move(other.socket.clone())}
+    { }
+
+    /**
+     * @brief Copy the given wrapped socket.
+     * 
+     * @note Autoclose should most likely be set to false on 
+     * the either one or both of the sockets to prevent accidentally 
+     * closing the socket.
+     * 
+     * @param socket The warpped socket to copy.
+     */
+    SockCopy & operator=(const SockCopy & other)
+    {
+        socket = std::move(other.socket.clone());
+    }
+
+    /**
+     * @brief Get the wrapped socket
+     */
+    SockType & getSocket()
+    {
+        return socket;
+    }
+
+    /**
+     * @brief Get the wrapped socket
+     */
+    SockType & operator() ()
+    {
+        return socket;
+    }
+
+};
+
+
+SockCopy<TcpStream> wrapCopy(TcpStream & other, bool disableAutoclose = true)
+{
+    if (disableAutoclose) other.setAutoclose(false);
+    return SockCopy<TcpStream>(other);
+}
+
+SockCopy<TcpListener> wrapCopy(TcpListener & other, bool disableAutoclose = true)
+{
+    if (disableAutoclose) other.setAutoclose(false);
+    return SockCopy<TcpListener>(other);
+}
+
+SockCopy<UdpSocket> wrapCopy(UdpSocket & other, bool disableAutoclose = true)
+{
+    if (disableAutoclose) other.setAutoclose(false);
+    return SockCopy<UdpSocket>(other);
+}
+
+
+SockCopy<TcpStream> wrapCopy(TcpStream && other, bool disableAutoclose = true)
+{
+    if (disableAutoclose) other.setAutoclose(false);
+    return SockCopy<TcpStream>(std::move(other));
+}
+
+SockCopy<TcpListener> wrapCopy(TcpListener && other, bool disableAutoclose = true)
+{
+    if (disableAutoclose) other.setAutoclose(false);
+    return SockCopy<TcpListener>(std::move(other));
+}
+
+SockCopy<UdpSocket> wrapCopy(UdpSocket && other, bool disableAutoclose = true)
+{
+    if (disableAutoclose) other.setAutoclose(false);
+    return SockCopy<UdpSocket>(std::move(other));
+}
+
+
+} // namespace netlib
+
+#endif // _SOCKCOPY_HPP
\ No newline at end of file