diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2025-06-15 13:59:30 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2025-06-16 22:22:10 +0800 |
| commit | 08688972ae56b474e2e2fd954c5caaeb1233a1be (patch) | |
| tree | d44d051821e94283da2ca07862c1679ded6a9f3d /include/libsock/server | |
| parent | f93f73cdd3c7473e358b18c6f6add5f4d34ba5d6 (diff) | |
init: server
Diffstat (limited to 'include/libsock/server')
| -rw-r--r-- | include/libsock/server/client.hpp | 105 | ||||
| -rw-r--r-- | include/libsock/server/server.hpp | 25 |
2 files changed, 130 insertions, 0 deletions
diff --git a/include/libsock/server/client.hpp b/include/libsock/server/client.hpp new file mode 100644 index 0000000..b86b440 --- /dev/null +++ b/include/libsock/server/client.hpp @@ -0,0 +1,105 @@ +#pragma once + +#include "misc/FileDescriptor.hpp" +#include "misc/memory.hpp" +#include <format> +#include <functional> +#include <netinet/in.h> +#include <optional> +#include <string> +#include <sys/socket.h> +#include <thread> +#include <vector> + +namespace LibSock { +namespace Client { + +struct SRecvData { + std::string data; + const size_t size = 1024; + bool good = false; + + bool isEmpty() const; + void sanitize(); + + static constexpr char asciiEscape = 0x1B; // +}; + +enum eEventType : std::uint8_t { + READ, + WRITE +}; + +class Client { + public: + Client(bool track = false, bool oneShot = true); + ~Client(); + + const std::string &getName() const; + const std::string &getIp() const; + bool isAdmin() const; + + UP<SRecvData> read(std::optional<std::function<void(const SRecvData &)>> cb = std::nullopt); + UP<SRecvData> read(const std::string &msg, std::optional<std::function<void(const SRecvData &)>> cb = std::nullopt); + bool write(const std::string &msg, std::optional<std::function<void(const SRecvData &)>> cb = std::nullopt); + template <typename... Args> + bool write(std::format_string<Args...> fmt, Args &&...args); + + void run(); + + bool isValid(); + + private: + WP<Client> self; + SP<CFileDescriptor> m_sockfd; + sockaddr_in m_addr; + socklen_t m_addrLen = sizeof(m_addr); + std::string m_name; + std::string m_ip; + int m_port; + bool m_track; + bool m_oneShot; + + std::optional<std::string> m_szReading = std::nullopt; + + void recvLoop(); + + friend class Clients; +}; + +struct SData { + std::string msg; + std::optional<WP<Client>> sender = std::nullopt; + bool admin = false; +}; + +class Clients { + public: + Clients(); + ~Clients(); + + void newClient(std::optional<std::function<void()>> cb = std::nullopt); + + void run(std::optional<std::function<void()>> cb = std::nullopt); + void broadcast(const std::string &msg, std::optional<WP<Client>> self = std::nullopt); // second param only specified when we want to exclude the sender + void kick(WP<Client> client, const bool kill = false, const std::string &reason = ""); + void addClient(const Client &client); + + bool nameExists(const std::string &name); + void shutdownClients(); + + SP<Client> getByName(const std::string &name) const; + SP<Client> getByIp(const std::string &ip) const; + std::vector<SP<Client>> getClients() const; + std::vector<SData> getDatas() const; + + private: + void broadcast(const SData &msg); + + std::vector<std::pair<std::jthread, SP<Client>>> m_vClients; + std::vector<SData> m_vDatas; +}; +inline SP<Clients> pClients; + +} // namespace Client +} // namespace LibSock diff --git a/include/libsock/server/server.hpp b/include/libsock/server/server.hpp new file mode 100644 index 0000000..c97c945 --- /dev/null +++ b/include/libsock/server/server.hpp @@ -0,0 +1,25 @@ +#pragma once +#include "misc/FileDescriptor.hpp" +#include "misc/memory.hpp" +#include <mutex> +#include <netinet/in.h> + +namespace LibSock { +namespace Server { + +class Server { + public: + Server(uint16_t port, bool reuseaddr = true, bool keepalive = false); + ~Server(); + SP<CFileDescriptor> getSocket() const; + + private: + SP<CFileDescriptor> m_sockfd; + sockaddr_in m_addr; + uint16_t m_port; + + mutable std::mutex m_mutex; +}; +inline UP<Server> pServer; +} // namespace Server +} // namespace LibSock |
