aboutsummaryrefslogtreecommitdiff
path: root/client/src
diff options
context:
space:
mode:
authoralpine <[email protected]>2020-06-04 16:13:19 +0200
committeralpine <[email protected]>2020-06-04 16:13:19 +0200
commit28f66dee8a9fe49aadb5c1d67de48d9232363963 (patch)
tree00f6bfd0c2120d005c833301830d167b0753feb3 /client/src
downloadloader-28f66dee8a9fe49aadb5c1d67de48d9232363963.tar.xz
loader-28f66dee8a9fe49aadb5c1d67de48d9232363963.zip
Initial commit
Diffstat (limited to 'client/src')
-rw-r--r--client/src/client/client.cpp35
-rw-r--r--client/src/client/client.h47
-rw-r--r--client/src/client/packet.h45
-rw-r--r--client/src/include.h63
-rw-r--r--client/src/main.cpp29
-rw-r--r--client/src/util/events.h24
-rw-r--r--client/src/util/io.cpp12
-rw-r--r--client/src/util/io.h7
8 files changed, 262 insertions, 0 deletions
diff --git a/client/src/client/client.cpp b/client/src/client/client.cpp
new file mode 100644
index 0000000..9fe2e36
--- /dev/null
+++ b/client/src/client/client.cpp
@@ -0,0 +1,35 @@
+#include "../include.h"
+#include "client.h"
+
+bool tcp::client::start(const std::string_view server_ip,
+ const uint16_t &port) {
+#ifdef WINDOWS
+ WSADATA data;
+ int res = WSAStartup(MAKEWORD(2, 2), &data);
+ if (res != 0) {
+ io::logger->error("failed to initialize WSA.");
+ return false;
+ }
+#endif
+
+ m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (m_socket == -1) {
+ io::logger->error("failed to create socket.");
+ return false;
+ }
+
+ sockaddr_in server_addr;
+
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_addr.s_addr = inet_addr(server_ip.data());
+ server_addr.sin_port = htons(port);
+
+ int ret = connect(m_socket, reinterpret_cast<sockaddr *>(&server_addr),
+ sizeof(server_addr));
+ if (ret < 0) {
+ io::logger->error("failed to connect to server.");
+ return false;
+ }
+
+ return true;
+}
diff --git a/client/src/client/client.h b/client/src/client/client.h
new file mode 100644
index 0000000..8f14071
--- /dev/null
+++ b/client/src/client/client.h
@@ -0,0 +1,47 @@
+#pragma once
+#include "../util/io.h"
+#include "../util/events.h"
+
+namespace tcp {
+
+enum client_state : uint8_t {
+ idle = 0,
+ active,
+ standby
+};
+
+class client {
+ int m_socket;
+ std::atomic<uint8_t> m_state;
+
+ event<std::string> receive_event;
+
+ public:
+ client() : m_socket{-1}, m_state{0} {}
+ bool start(const std::string_view server_ip, const uint16_t &port);
+
+ bool send_message(const std::string_view msg) {
+ int ret = send(m_socket, msg.data(), msg.size(), 0);
+ return ret == msg.size();
+ }
+
+ int get_socket() { return m_socket; }
+ bool is_active() { return m_state == client_state::active; }
+ void set_state(const uint8_t &state) { m_state = state; }
+ auto &on_recv() { return receive_event; }
+
+ static void read(client &client) {
+ std::array<char, 256> buf;
+ while (client.is_active()) {
+ int ret = recv(client.get_socket(), &buf[0], buf.size(), 0);
+ if (ret <= 0) {
+ io::logger->error("connection lost.");
+ break;
+ }
+
+ std::string msg(buf.data(), ret);
+ client.on_recv().call(msg);
+ }
+ }
+};
+} // namespace tcp
diff --git a/client/src/client/packet.h b/client/src/client/packet.h
new file mode 100644
index 0000000..b61c4e2
--- /dev/null
+++ b/client/src/client/packet.h
@@ -0,0 +1,45 @@
+#pragma once
+
+namespace tcp {
+ constexpr size_t uid_len = 10;
+ struct packet_t {
+ std::string message;
+ char action;
+ std::array<char, uid_len> uid;
+
+ // parse packet from server message after decryption
+ bool parse(const std::string msg) {
+ // first 10 bytes is the uid
+ bool res = set_uid(msg.substr(0, uid_len));
+ if(!res) {
+ return false;
+ }
+
+ action = msg[uid_len];
+ const bool stream = static_cast<bool>(msg[uid_len + 1]);
+ if(stream) {
+ const size_t size = std::stoll(msg.substr(uid_len + 2));
+
+ // receive stream
+
+ return true;
+ }
+
+ message = msg.substr(uid_len + 2);
+ return true;
+ }
+ bool set_uid(const std::string_view uid_str) {
+ const size_t uid_str_len = uid_str_len.size();
+ if(uid_str_len != uid_len) {
+ io::logger->error("packet uid len mismatch!");
+ return false;
+ }
+
+ for(size_t i = 0; i < uid_len; ++i) {
+ uid[i] = uid_str[i];
+ }
+
+ return true;
+ }
+ };
+};
diff --git a/client/src/include.h b/client/src/include.h
new file mode 100644
index 0000000..e2c647b
--- /dev/null
+++ b/client/src/include.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#if defined(_WIN32) || defined(_WIN64)
+#define WINDOWS
+#endif
+
+#ifdef WINDOWS
+#define _CRT_SECURE_NO_WARNINGS
+#define _WINSOCK_DEPRECATED_NO_WARNINGS
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+
+#include <windows.h>
+#include <stdio.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <iphlpapi.h>
+
+#pragma comment( lib, "ws2_32.lib" )
+#endif
+
+#include <stdio.h>
+#include <algorithm>
+#include <array>
+#include <chrono>
+#include <cstring>
+#include <fstream>
+#include <functional>
+#include <iostream>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <system_error>
+#include <thread>
+#include <vector>
+#include <unordered_map>
+#include <optional>
+#include <iomanip>
+#include <map>
+#include <random>
+#include <list>
+#include <utility>
+#include <atomic>
+#include <mutex>
+#include <future>
+#include <any>
+
+#ifndef WINDOWS
+
+#define closesocket(socket) close(socket)
+
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+#include <spdlog/fmt/fmt.h>
+#include <spdlog/spdlog.h>
+#include <spdlog/sinks/basic_file_sink.h>
+#include <spdlog/sinks/stdout_color_sinks.h> \ No newline at end of file
diff --git a/client/src/main.cpp b/client/src/main.cpp
new file mode 100644
index 0000000..1dc9db2
--- /dev/null
+++ b/client/src/main.cpp
@@ -0,0 +1,29 @@
+#include "include.h"
+#include "util/io.h"
+#include "client/client.h"
+
+int main(int argc, char *argv[]) {
+ tcp::client client;
+ if (client.start("127.0.0.1", 6666)) {
+ io::logger->info("connected.");
+ client.set_state(tcp::client_state::active);
+ }
+
+ client.on_recv().add([&](std::string msg) {
+ io::logger->info(msg);
+ });
+
+ std::thread t{tcp::client::read, std::ref(client)};
+
+ while (client.is_active()) {
+ std::string p;
+ getline(std::cin, p);
+
+ bool ret = client.send_message(p);
+ if (!ret) {
+ break;
+ }
+ }
+
+ t.join();
+}
diff --git a/client/src/util/events.h b/client/src/util/events.h
new file mode 100644
index 0000000..b8d7781
--- /dev/null
+++ b/client/src/util/events.h
@@ -0,0 +1,24 @@
+#pragma once
+
+template <typename... Args>
+class event {
+ using func_type = std::function<void(Args...)>;
+
+ std::mutex event_lock;
+ std::list<func_type> m_funcs;
+
+ public:
+ void add(const func_type& func) {
+ std::lock_guard<std::mutex> lock(event_lock);
+
+ m_funcs.push_back(std::move(func));
+ }
+
+ void call(Args... params) {
+ std::lock_guard<std::mutex> lock(event_lock);
+
+ for (auto& func : m_funcs) {
+ if (func) func(std::forward<Args>(params)...);
+ }
+ }
+}; \ No newline at end of file
diff --git a/client/src/util/io.cpp b/client/src/util/io.cpp
new file mode 100644
index 0000000..06d2b9a
--- /dev/null
+++ b/client/src/util/io.cpp
@@ -0,0 +1,12 @@
+#include "../include.h"
+#include "io.h"
+
+std::shared_ptr<spdlog::logger> io::logger;
+
+void io::init() {
+ spdlog::sink_ptr sink =
+ std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
+ sink->set_pattern("%^~>%$ %v");
+
+ logger = std::make_shared<spdlog::logger>("client", sink);
+}
diff --git a/client/src/util/io.h b/client/src/util/io.h
new file mode 100644
index 0000000..8eae321
--- /dev/null
+++ b/client/src/util/io.h
@@ -0,0 +1,7 @@
+#pragma once
+
+namespace io {
+extern std::shared_ptr<spdlog::logger> logger;
+
+void init();
+}; // namespace io