Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions Tests/socket_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
Expand Down Expand Up @@ -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);

Expand All @@ -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();
Expand Down
4 changes: 3 additions & 1 deletion src/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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")
DECLARE_EXCEPTION(SocketAcceptException, "Socket accept error")
DECLARE_EXCEPTION(InetPtonException, "inet_pton failed")
33 changes: 21 additions & 12 deletions src/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,45 +42,54 @@ 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<sockaddr *>(&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<struct sockaddr *>(&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<sockaddr *>(&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<struct sockaddr *>(&addr), sizeof(addr)) == INVALID_SOCKET)
{
throw SocketBindException(std::to_string(GetSocketError()));
}
}

void Socket::Listen(int backlog)
{
if (::listen(m_socket, backlog) == INVALID_SOCKET)
if (::listen(m_socket, backlog) != 0)
{
throw SocketListenException(std::to_string(GetSocketError()));
}
}

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<struct sockaddr *>(&client_addr), &client_addr_size);
if (client_socket == INVALID_SOCKET)
{
throw SocketAcceptException(std::to_string(GetSocketError()));
Expand Down
7 changes: 4 additions & 3 deletions src/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading