aboutsummaryrefslogtreecommitdiff
path: root/works/life
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2021-06-08 18:25:36 +0800
committercrupest <crupest@outlook.com>2021-06-08 18:25:36 +0800
commitf7d73f1bf08aaca98e789a6d6c56d672cc0c4c9f (patch)
treea059a5c93ac38c5826bb59555fa654cebc6ca951 /works/life
parentd9756de78c161c2d33a9d32d2cb1eaa68be1744e (diff)
downloadcrupest-f7d73f1bf08aaca98e789a6d6c56d672cc0c4c9f.tar.gz
crupest-f7d73f1bf08aaca98e789a6d6c56d672cc0c4c9f.tar.bz2
crupest-f7d73f1bf08aaca98e789a6d6c56d672cc0c4c9f.zip
import(life): ...
Diffstat (limited to 'works/life')
-rw-r--r--works/life/computer-network-experiment/Common.cpp33
-rw-r--r--works/life/computer-network-experiment/Common.h6
-rw-r--r--works/life/computer-network-experiment/client.cpp11
-rw-r--r--works/life/computer-network-experiment/server.cpp34
4 files changed, 53 insertions, 31 deletions
diff --git a/works/life/computer-network-experiment/Common.cpp b/works/life/computer-network-experiment/Common.cpp
index ec6fd1a..1df4d56 100644
--- a/works/life/computer-network-experiment/Common.cpp
+++ b/works/life/computer-network-experiment/Common.cpp
@@ -1,6 +1,7 @@
#include "Common.h"
#include "IO.h"
+#include <memory>
#ifdef WIN32
#include <Windows.h>
@@ -70,7 +71,7 @@ void BeforeExit() {
SignalAndWaitForOutputThreadStop();
}
-void SafeSend(int socket, std::string_view buffer) {
+bool SafeSend(int socket, std::string_view buffer) {
const int total_byte_count = buffer.size();
int byte_count_sent = 0;
int retry_count = 0;
@@ -78,55 +79,49 @@ void SafeSend(int socket, std::string_view buffer) {
while (true) {
// Now we have sent all data.
if (byte_count_sent == total_byte_count)
- break;
+ return true;
auto byte_actually_sent = send(socket, buffer.data() + byte_count_sent,
buffer.size() - byte_count_sent, 0);
// send failed
if (byte_actually_sent == -1) {
- SendOutput(OutputType::Error, CRUT("Failed to send!\n"));
- CloseSocket(socket);
- break;
+ return false;
}
byte_count_sent += byte_actually_sent;
}
}
-std::string SafeReadUntil(int socket, char c, std::string &rest) {
- std::string result = rest;
+bool SafeReadUntil(int socket, char c, std::string &data, std::string &rest) {
+ data = rest;
const int buffer_size = 100;
- char *buffer = new char[buffer_size];
+ char buffer[buffer_size];
while (true) {
int received_number = recv(socket, buffer, buffer_size, 0);
if (received_number == -1) {
- PrintErrorMessageAndExit(CRUT("Failed to recv."));
+ return false;
}
- bool b = false;
+ bool end = false;
for (int i = 0; i < received_number; i++) {
if (buffer[i] == c) {
- result.append(buffer, i);
+ data.append(buffer, i);
rest = std::string(buffer + i + 1, received_number - i - 1);
- b = true;
+ end = true;
break;
}
}
- if (b)
- break;
+ if (end)
+ return true;
- result.append(buffer, received_number);
+ data.append(buffer, received_number);
}
-
- delete[] buffer;
-
- return result;
}
int main() {
diff --git a/works/life/computer-network-experiment/Common.h b/works/life/computer-network-experiment/Common.h
index a4472c7..1e6c277 100644
--- a/works/life/computer-network-experiment/Common.h
+++ b/works/life/computer-network-experiment/Common.h
@@ -48,5 +48,7 @@ int CloseSocket(int socket);
void BeforeExit();
-void SafeSend(int socket, std::string_view buffer);
-std::string SafeReadUntil(int socket, char c, std::string &rest);
+// Return false for error.
+bool SafeSend(int socket, std::string_view buffer);
+// Return false for error.
+bool SafeReadUntil(int socket, char c, std::string &data, std::string &rest);
diff --git a/works/life/computer-network-experiment/client.cpp b/works/life/computer-network-experiment/client.cpp
index c206856..73ae52f 100644
--- a/works/life/computer-network-experiment/client.cpp
+++ b/works/life/computer-network-experiment/client.cpp
@@ -75,9 +75,12 @@ int Main() {
break;
}
- std::string s = SafeReadUntil(client_socket, '\n', rest);
+ std::string data;
+ if (!SafeReadUntil(client_socket, '\n', data, rest)) {
+ PrintErrorMessageAndExit(CRUT("Failed to receive message.\n"));
+ }
- SendOutput(CRUT("Recived a message:\n{}\n"), ConvertCharString(s));
+ SendOutput(CRUT("Recived a message:\n{}\n"), ConvertCharString(data));
}
});
receive_thread.detach();
@@ -89,7 +92,9 @@ int Main() {
std::string s;
if (send_queue.read(s)) {
- SafeSend(client_socket, s);
+ if (!SafeSend(client_socket, s)) {
+ PrintErrorMessageAndExit(CRUT("Failed to send message to server."));
+ }
}
}
diff --git a/works/life/computer-network-experiment/server.cpp b/works/life/computer-network-experiment/server.cpp
index 9654687..03d27ad 100644
--- a/works/life/computer-network-experiment/server.cpp
+++ b/works/life/computer-network-experiment/server.cpp
@@ -36,6 +36,7 @@ void PrintHelp() {
struct Connection {
int id;
std::thread thread;
+ std::thread receive_thread;
int socket;
sockaddr_in address;
String address_string;
@@ -65,13 +66,19 @@ void ResponseThreadProc(Connection *connection) {
connection->address_string = fmt::format(CRUT("{}:{}"), host, port);
std::string rest;
+ std::string name_data;
+ if (!SafeReadUntil(connection->socket, '\n', name_data, rest)) {
+ SendOutput(OutputType::Error, CRUT("Failed to read name of {}.\n"),
+ connection->address_string);
+ CloseSocket(connection->socket);
+ return;
+ }
- std::string n = SafeReadUntil(connection->socket, '\n', rest);
- connection->name = ConvertCharString(n);
+ connection->name = ConvertCharString(name_data);
SendOutput(OutputColor::Green, CRUT("Connected to {}, whose name is {}.\n"),
connection->address_string, connection->name);
- std::thread revieve_thread(
+ connection->receive_thread = std::thread(
[](Connection *connection) {
std::string rest;
while (true) {
@@ -79,14 +86,22 @@ void ResponseThreadProc(Connection *connection) {
break;
}
- std::string s = SafeReadUntil(connection->socket, '\n', rest);
+ std::string data;
+
+ if (!SafeReadUntil(connection->socket, '\n', data, rest)) {
+ SendOutput(OutputType::Error,
+ CRUT("Failed read data from socket of {}({}).\n"),
+ connection->name, connection->address_string);
+ connection->cancellation_source.requestCancellation();
+ return;
+ }
SendOutput(CRUT("{}({}) send a message:\n{}\n"), connection->name,
- connection->address_string, ConvertCharString(s));
+ connection->address_string, ConvertCharString(data));
}
},
connection);
- revieve_thread.detach();
+ connection->receive_thread.detach();
while (true) {
if (connection->cancellation_source.isCancellationRequested()) {
@@ -95,7 +110,12 @@ void ResponseThreadProc(Connection *connection) {
std::string s;
if (connection->send_queue.read(s)) {
- SafeSend(connection->socket, s);
+ if (!SafeSend(connection->socket, s)) {
+ SendOutput(OutputType::Error, CRUT("Failed send data to {}({}).\n"),
+ connection->name, connection->address_string);
+ connection->cancellation_source.requestCancellation();
+ break;
+ }
}
}