aboutsummaryrefslogtreecommitdiff
path: root/store/works/life/computer-network-experiment/client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'store/works/life/computer-network-experiment/client.cpp')
-rw-r--r--store/works/life/computer-network-experiment/client.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/store/works/life/computer-network-experiment/client.cpp b/store/works/life/computer-network-experiment/client.cpp
new file mode 100644
index 0000000..73ae52f
--- /dev/null
+++ b/store/works/life/computer-network-experiment/client.cpp
@@ -0,0 +1,103 @@
+/** Created by crupest.
+ * This is the client program.
+ */
+
+#include "Common.h"
+#include "IO.h"
+
+#include <folly/CancellationToken.h>
+#include <folly/ProducerConsumerQueue.h>
+
+#ifdef WIN32
+#include <Windows.h>
+#include <winsock.h>
+#else
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#endif
+
+const auto connect_address = "127.0.0.1"; // control connect address
+const u_short port = 1234; // control connect port
+
+namespace {
+folly::ProducerConsumerQueue<std::string> send_queue(100);
+folly::CancellationSource cancellation_source;
+} // namespace
+
+void PrintHelp() {
+ SendOutput(CRUT("Input anything to send to server. Or just enter to receive "
+ "lastest messages from server.\n"));
+}
+
+void OnInputLine(StringView line) {
+ if (line.empty()) {
+ return;
+ } else {
+ send_queue.write(ConvertCharStringBack(line) + '\n');
+ }
+}
+
+int Main() {
+ int client_socket;
+
+ if ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+ PrintErrorMessageAndExit(CRUT("Failed to create socket!\n"));
+ }
+
+ sockaddr_in server_address;
+
+ server_address.sin_family = AF_INET;
+ server_address.sin_port = htons(port);
+ server_address.sin_addr.s_addr = inet_addr(connect_address);
+ memset(&(server_address.sin_zero), 0, sizeof(server_address.sin_zero));
+
+ if (connect(client_socket, (sockaddr *)&server_address, sizeof(sockaddr)) ==
+ -1) {
+ PrintErrorMessageAndExit(CRUT("Failed to connect!"));
+ }
+
+ output_stream << CRUT("Please input your name:\n> ");
+ String name = ReadInputLine();
+
+ PrintHelp();
+
+ StartIOThread();
+
+ name.push_back(CRUT('\n'));
+ auto name_data = ConvertCharStringBack(name);
+ SafeSend(client_socket, name_data);
+
+ std::thread receive_thread([client_socket] {
+ std::string rest;
+ while (true) {
+ if (cancellation_source.isCancellationRequested()) {
+ break;
+ }
+
+ 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(data));
+ }
+ });
+ receive_thread.detach();
+
+ while (true) {
+ if (cancellation_source.isCancellationRequested()) {
+ break;
+ }
+
+ std::string s;
+ if (send_queue.read(s)) {
+ if (!SafeSend(client_socket, s)) {
+ PrintErrorMessageAndExit(CRUT("Failed to send message to server."));
+ }
+ }
+ }
+
+ CloseSocket(client_socket);
+ return 0;
+}