From 5783b8951d97ec95e09c7bdcd83ff687cc2b4d58 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 18 Aug 2025 11:23:16 +0300 Subject: [PATCH] Impl `inet_pton` --- Tests/socket_tests.cpp | 17 ++++++++++------- src/exceptions.h | 4 +++- src/socket.cpp | 33 +++++++++++++++++++++------------ src/socket.h | 7 ++++--- 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/Tests/socket_tests.cpp b/Tests/socket_tests.cpp index e89ec21..d516ed7 100644 --- a/Tests/socket_tests.cpp +++ b/Tests/socket_tests.cpp @@ -5,6 +5,7 @@ constexpr auto TEST_IP_ADDR = "127.0.0.1"; +constexpr auto TEST_IP_ADDR_LISTEN = "0.0.0.0"; #ifdef _WIN32 constexpr auto TEST_PORT_1 = 8001; constexpr auto TEST_PORT_2 = 8002; @@ -23,7 +24,7 @@ TEST(create_tcp_sock, BasicAssertions) { // Create a listening socket Socket sock1 = Socket(); - sock1.Bind(TEST_PORT_1); + sock1.Bind(TEST_IP_ADDR_LISTEN, TEST_PORT_1); sock1.Listen(1); // Connect to listening socket Socket sock2 = Socket(); @@ -52,12 +53,12 @@ TEST(try_bind_twice, HasCertainMessage) { // Bind a socket Socket sock1 = Socket(); - sock1.Bind(TEST_PORT_2); + sock1.Bind(TEST_IP_ADDR_LISTEN, TEST_PORT_2); // Bind socket with same port Socket sock2 = Socket(); EXPECT_THROW( { - sock2.Bind(TEST_PORT_2); + sock2.Bind(TEST_IP_ADDR_LISTEN, TEST_PORT_2); }, SocketBindException); @@ -69,17 +70,19 @@ TEST(try_connect_to_closed_peer, BasicAssertions) { // Create a listening socket Socket sock1 = Socket(); - auto connect_result = sock1.Connect(TEST_IP_ADDR, TEST_PORT_3); + EXPECT_THROW( + { + auto connect_result = sock1.Connect(TEST_IP_ADDR, TEST_PORT_3); + }, + SocketConnectException); sock1.Close(); - // Expect connection error. - EXPECT_EQ(connect_result, -1); } TEST(partial_recv, BasicAssertions) { // Create a listening socket Socket sock1 = Socket(); - sock1.Bind(TEST_PORT_4); + sock1.Bind(TEST_IP_ADDR_LISTEN, TEST_PORT_4); sock1.Listen(1); // Connect to listening socket Socket sock2 = Socket(); diff --git a/src/exceptions.h b/src/exceptions.h index 55aad33..130bc95 100644 --- a/src/exceptions.h +++ b/src/exceptions.h @@ -25,6 +25,8 @@ class SocketException: public std::exception { DECLARE_EXCEPTION(SocketCreateException, "Error creating socket") +DECLARE_EXCEPTION(SocketConnectException, "Error connecting socket") DECLARE_EXCEPTION(SocketBindException, "Socket bind error") DECLARE_EXCEPTION(SocketListenException, "Socket listen error") -DECLARE_EXCEPTION(SocketAcceptException, "Socket accept error") \ No newline at end of file +DECLARE_EXCEPTION(SocketAcceptException, "Socket accept error") +DECLARE_EXCEPTION(InetPtonException, "inet_pton failed") \ No newline at end of file diff --git a/src/socket.cpp b/src/socket.cpp index 4b7ace7..d41c35e 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -42,27 +42,36 @@ Socket& Socket::operator=(Socket&& other) noexcept { other.m_socket = INVALID_SOCKET; #ifdef _WIN32 m_wsaData = other.m_wsaData; - ZeroMemory(&other.m_wsaData, sizeof(other.m_wsaData)); #endif return *this; } -int Socket::Connect(std::string address, int port) +int Socket::Connect(const std::string& address, int port) { - sockaddr_in addr = {0}; + struct sockaddr_in addr = {0}; addr.sin_family = AF_INET; addr.sin_port = htons(port); - addr.sin_addr.s_addr = inet_addr(address.c_str()); - return ::connect(m_socket, reinterpret_cast(&addr), sizeof(addr)); + auto response = inet_pton(AF_INET, address.c_str(), &addr.sin_addr); + if (response != 1) { + throw InetPtonException(std::to_string(GetSocketError())); + } + response = ::connect(m_socket, reinterpret_cast(&addr), sizeof(addr)); + if (response != 0) { + throw SocketConnectException(std::to_string(GetSocketError())); + } + return response; } -void Socket::Bind(int port) +void Socket::Bind(const std::string& address, int port) { - sockaddr_in addr = {0}; + struct sockaddr_in addr = {0}; addr.sin_family = AF_INET; addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_ANY); - if (::bind(m_socket, reinterpret_cast(&addr), sizeof(addr)) == INVALID_SOCKET) + auto response = inet_pton(AF_INET, address.c_str(), &addr.sin_addr); + if (response != 1) { + throw InetPtonException(std::to_string(GetSocketError())); + } + if (::bind(m_socket, reinterpret_cast(&addr), sizeof(addr)) == INVALID_SOCKET) { throw SocketBindException(std::to_string(GetSocketError())); } @@ -70,7 +79,7 @@ void Socket::Bind(int port) void Socket::Listen(int backlog) { - if (::listen(m_socket, backlog) == INVALID_SOCKET) + if (::listen(m_socket, backlog) != 0) { throw SocketListenException(std::to_string(GetSocketError())); } @@ -78,9 +87,9 @@ void Socket::Listen(int backlog) Socket Socket::Accept() { - sockaddr_in client_addr; + struct sockaddr_in client_addr = {0}; socklen_t client_addr_size = sizeof(client_addr); - SOCKET client_socket = ::accept(m_socket, (sockaddr *)&client_addr, &client_addr_size); + SOCKET client_socket = ::accept(m_socket, reinterpret_cast(&client_addr), &client_addr_size); if (client_socket == INVALID_SOCKET) { throw SocketAcceptException(std::to_string(GetSocketError())); diff --git a/src/socket.h b/src/socket.h index 7ae160e..ec4a22b 100644 --- a/src/socket.h +++ b/src/socket.h @@ -19,13 +19,14 @@ class Socket { /// @brief Connect to endpoint. /// @param address (std::string). /// @param port (int). - /// @return operation result (int) - `0` if connected, `-1` if there was an + /// @return operation result (int) /// error. - int Connect(std::string address, int port); + int Connect(const std::string& address, int port); /// @brief Bind operation. + /// @param address (std::string). /// @param port - port to bind. - void Bind(int port); + void Bind(const std::string& address, int port); /// @brief Allows to listen for connections. /// @param backlog (int) - number of pending connections the socket will hold.