diff --git a/src/net/socketaddress.hpp b/src/net/socketaddress.hpp
index c32867dc1a85a49b8d2bdff152565f870dd04e5a..2ce0e6c73211a956543fe3d39e1023a7c7ebf892 100644
--- a/src/net/socketaddress.hpp
+++ b/src/net/socketaddress.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include <arpa/inet.h>
+
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -9,6 +11,8 @@
 #include <netinet/ip6.h>
 
 #include <functional>
+#include <string>
+#include <sstream>
 
 #include "macros.hpp"
 #include "net/netio_exception.hpp"
@@ -136,6 +140,42 @@ COMPILER_RESTORE("-Weffc++");
     socklen_t size() const {
         return len;
     }
+
+    std::string str() const {
+        std::ostringstream oss;
+        oss << "SocketAddress: ";
+        const int buffer_size = 1024;
+        char buffer[buffer_size];
+
+        switch (this->family()) {
+        case AF_INET:
+            inet_ntop(AF_INET, &((sockaddr_in*)&addr)->sin_addr, buffer, buffer_size);
+            oss << "IPv4 " << buffer << ":" << ntohs(((sockaddr_in*)&addr)->sin_port);
+            break;
+        case AF_INET6:
+            inet_ntop(AF_INET6, &((sockaddr_in6*)&addr)->sin6_addr, buffer, buffer_size);
+            oss << "IPv6 ["<< buffer << "]:" << ntohs(((sockaddr_in6*)&addr)->sin6_port);
+            break;
+        case AF_UNIX:
+            oss << "FileSocket " << ((sockaddr_un*)&addr)->sun_path;
+            break;
+        case AF_NETLINK: {
+            const auto nl_sock_ptr = (sockaddr_nl*) &addr;
+            oss << "Netlink g:" << nl_sock_ptr->nl_groups << " p:" << nl_sock_ptr->nl_pad << " pid:" << nl_sock_ptr->nl_pid;
+            break;
+        }
+        default:
+            oss << "Unknown Socket Address Type";
+            break;
+        }
+
+        return oss.str();
+    }
+
 };
 
+static inline std::ostream& operator<<(std::ostream& os, const socketaddr& sockaddr) {
+    return os << sockaddr.str();
+}
+
 }