Skip to content

Commit 2ba8240

Browse files
committed
Network: Fix send/receive message
1 parent fd8a0a1 commit 2ba8240

2 files changed

Lines changed: 89 additions & 19 deletions

File tree

modules/Network/Socket.mpp

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,16 +118,52 @@ export namespace CppUtils::Network
118118
#endif
119119

120120
inline Socket(const Socket&) = delete;
121-
inline Socket(Socket&&) noexcept = default;
121+
122+
inline Socket(Socket&& other) noexcept:
123+
m_domain{other.m_domain},
124+
m_isBlocking{other.m_isBlocking},
125+
m_socket{other.m_socket}
126+
{
127+
#if defined(OS_WINDOWS)
128+
other.m_socket = INVALID_SOCKET;
129+
#else
130+
other.m_socket = -1;
131+
#endif
132+
}
133+
122134
inline auto operator=(const Socket&) -> Socket& = delete;
123-
inline auto operator=(Socket&&) noexcept -> Socket& = default;
135+
136+
inline auto operator=(Socket&& other) noexcept -> Socket&
137+
{
138+
if (this != &other)
139+
{
140+
#if defined(OS_WINDOWS)
141+
if (m_socket != INVALID_SOCKET)
142+
::closesocket(m_socket);
143+
#else
144+
if (m_socket != -1)
145+
::close(m_socket);
146+
#endif
147+
m_domain = other.m_domain;
148+
m_isBlocking = other.m_isBlocking;
149+
m_socket = other.m_socket;
150+
#if defined(OS_WINDOWS)
151+
other.m_socket = INVALID_SOCKET;
152+
#else
153+
other.m_socket = -1;
154+
#endif
155+
}
156+
return *this;
157+
}
124158

125159
virtual inline ~Socket()
126160
{
127161
#if defined(OS_WINDOWS)
128-
::closesocket(m_socket);
162+
if (m_socket != INVALID_SOCKET)
163+
::closesocket(m_socket);
129164
#elif defined(OS_LINUX)
130-
::close(m_socket);
165+
if (m_socket != -1)
166+
::close(m_socket);
131167
#endif
132168
}
133169

@@ -159,10 +195,9 @@ export namespace CppUtils::Network
159195
if (::ioctlsocket(m_socket, static_cast<long>(FIONBIO), &mode) != 0)
160196
throw std::runtime_error{"CppUtils::Network::Socket::setBlocking: Failed to set blocking mode"};
161197
#elif defined(OS_LINUX)
162-
auto flags = ::fcntl(m_socket, F_GETFL, 0);
198+
auto flags = ::fcntl(m_socket, F_GETFL);
163199
if (flags == -1)
164200
throw std::runtime_error{"CppUtils::Network::Socket::setBlocking: Failed to get socket flags"};
165-
166201
if (enable)
167202
flags &= ~O_NONBLOCK;
168203
else
@@ -382,6 +417,8 @@ export namespace CppUtils::Network
382417
[[nodiscard]] inline auto receive<std::string>(std::size_t bufferSize) -> std::optional<std::string>
383418
{
384419
auto buffer = receive<std::vector<std::byte>>(bufferSize);
420+
if (not buffer.has_value())
421+
return std::nullopt;
385422
return std::string(reinterpret_cast<const char*>(std::data(buffer.value())), std::size(buffer.value()));
386423
}
387424

tests/Network/Network.mpp

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export namespace CppUtils::UnitTest::Network
77
{
88
inline auto _ = TestSuite{
99
"Network", {"Logger", "Thread/TryAsync"}, [](auto& suite) {
10+
using namespace std::literals;
1011
using Logger = CppUtils::Logger<"CppUtils">;
1112

1213
suite.addTest("Server Creation", [&] {
@@ -43,8 +44,35 @@ export namespace CppUtils::UnitTest::Network
4344
});
4445

4546
suite.addTest("Accept connection", [&] {
46-
using namespace std::chrono_literals;
47+
auto serverisReady = CppUtils::Thread::Event{};
48+
49+
auto serverListening = CppUtils::Thread::tryAsync([&] {
50+
auto server = CppUtils::Network::Server{};
51+
server.setReuseAddress(true);
52+
server.bind(8'080);
53+
server.listen();
54+
Logger::print("Server: Waiting for connections on port 8080...\n");
55+
serverisReady.notify();
56+
auto clientSocket = server.accept();
57+
suite.expect(clientSocket.has_value());
58+
Logger::print("Server: A new client has joined\n");
59+
});
4760

61+
auto clientConnecting = CppUtils::Thread::tryAsync([&] {
62+
serverisReady.wait();
63+
auto client = CppUtils::Network::Client{};
64+
Logger::print("Client: Attempting to connect...\n");
65+
client.connect("", 8'080);
66+
Logger::print("Client: Connected\n");
67+
});
68+
69+
if (auto clientResult = clientConnecting.get(); not clientResult.has_value())
70+
throw clientResult.error();
71+
if (auto serverResult = serverListening.get(); not serverResult.has_value())
72+
throw serverResult.error();
73+
});
74+
75+
suite.addTest("Blocking", [&] {
4876
auto serverisReady = CppUtils::Thread::Event{};
4977

5078
auto serverListening = CppUtils::Thread::tryAsync([&] {
@@ -57,6 +85,8 @@ export namespace CppUtils::UnitTest::Network
5785
auto clientSocket = server.accept();
5886
suite.expect(clientSocket.has_value());
5987
Logger::print("Server: A new client has joined\n");
88+
clientSocket->setBlocking(true);
89+
Logger::print("Server: Blocking enabled\n");
6090
});
6191

6292
auto clientConnecting = CppUtils::Thread::tryAsync([&] {
@@ -65,6 +95,8 @@ export namespace CppUtils::UnitTest::Network
6595
Logger::print("Client: Attempting to connect...\n");
6696
client.connect("", 8'080);
6797
Logger::print("Client: Connected\n");
98+
client.setBlocking(true);
99+
Logger::print("Client: Blocking enabled\n");
68100
});
69101

70102
if (auto clientResult = clientConnecting.get(); not clientResult.has_value())
@@ -73,10 +105,7 @@ export namespace CppUtils::UnitTest::Network
73105
throw serverResult.error();
74106
});
75107

76-
/*
77108
suite.addTest("Send/receive message (int)", [&] {
78-
using namespace std::chrono_literals;
79-
80109
auto serverisReady = CppUtils::Thread::Event{};
81110

82111
auto serverListening = CppUtils::Thread::tryAsync([&] {
@@ -130,8 +159,6 @@ export namespace CppUtils::UnitTest::Network
130159
});
131160

132161
suite.addTest("Send/receive message (std::string)", [&] {
133-
using namespace std::chrono_literals;
134-
135162
auto serverisReady = CppUtils::Thread::Event{};
136163

137164
auto serverListening = CppUtils::Thread::tryAsync([&] {
@@ -148,13 +175,16 @@ export namespace CppUtils::UnitTest::Network
148175
clientSocket.setBlocking(true);
149176
Logger::print("Server: Socket set to blocking mode\n");
150177

151-
auto message = clientSocket.receive<std::string>();
178+
auto messageLength = clientSocket.receive<std::size_t>().value();
179+
auto message = clientSocket.receive<std::string>(messageLength);
152180
suite.expect(message.has_value());
153181
Logger::print("Server: Message received: {}\n", message.value());
154182
suite.expectEqual(message.value(), "Hello server!");
155183

156-
clientSocket.send("Hello client!");
157-
Logger::print(R"(Server: Message sent: "Hello client!"\n)");
184+
auto messageToSend = "Hello client!"sv;
185+
clientSocket.send(std::size(messageToSend));
186+
clientSocket.send(messageToSend);
187+
Logger::print("Server: Message sent: \"Hello client!\"\n");
158188

159189
Logger::print("Server: Closing\n");
160190
});
@@ -163,13 +193,17 @@ export namespace CppUtils::UnitTest::Network
163193
serverisReady.wait();
164194
auto client = CppUtils::Network::Client{};
165195
Logger::print("Client: Attempting to connect...\n");
196+
client.setBlocking(true);
166197
client.connect("", 8'080);
167198
Logger::print("Client: Connected\n");
168199

169-
client.send("Hello server!");
170-
Logger::print(R"(Client: Message sent: "Hello server!"\n)");
200+
auto message = "Hello server!"sv;
201+
client.send(std::size(message));
202+
client.send(message);
203+
Logger::print("Client: Message sent: \"Hello server!\"\n");
171204

172-
auto response = client.receive<std::string>();
205+
auto responseLength = client.receive<std::size_t>().value();
206+
auto response = client.receive<std::string>(responseLength);
173207
suite.expect(response.has_value());
174208
Logger::print("Client: Message received: {}\n", response.value());
175209
suite.expectEqual(response.value(), "Hello client!");
@@ -182,6 +216,5 @@ export namespace CppUtils::UnitTest::Network
182216
if (auto serverResult = serverListening.get(); not serverResult.has_value())
183217
throw serverResult.error();
184218
});
185-
*/
186219
}};
187220
}

0 commit comments

Comments
 (0)