diff options
| author | alpine <[email protected]> | 2020-06-04 16:13:19 +0200 |
|---|---|---|
| committer | alpine <[email protected]> | 2020-06-04 16:13:19 +0200 |
| commit | 28f66dee8a9fe49aadb5c1d67de48d9232363963 (patch) | |
| tree | 00f6bfd0c2120d005c833301830d167b0753feb3 /client/src | |
| download | loader-28f66dee8a9fe49aadb5c1d67de48d9232363963.tar.xz loader-28f66dee8a9fe49aadb5c1d67de48d9232363963.zip | |
Initial commit
Diffstat (limited to 'client/src')
| -rw-r--r-- | client/src/client/client.cpp | 35 | ||||
| -rw-r--r-- | client/src/client/client.h | 47 | ||||
| -rw-r--r-- | client/src/client/packet.h | 45 | ||||
| -rw-r--r-- | client/src/include.h | 63 | ||||
| -rw-r--r-- | client/src/main.cpp | 29 | ||||
| -rw-r--r-- | client/src/util/events.h | 24 | ||||
| -rw-r--r-- | client/src/util/io.cpp | 12 | ||||
| -rw-r--r-- | client/src/util/io.h | 7 |
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 |