diff options
-rw-r--r-- | client/main.cpp | 10 | ||||
-rw-r--r-- | client/rl.h | 6 | ||||
-rw-r--r-- | client/sock.cpp | 75 | ||||
-rw-r--r-- | client/sock.h | 17 |
4 files changed, 89 insertions, 19 deletions
diff --git a/client/main.cpp b/client/main.cpp index 6aad0e3..36fc7bb 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -1,6 +1,7 @@ #include <cstdio> #include <cstdlib> #include <cstdint> +#include <exception> #include "rl.h" #include "sock.h" @@ -16,8 +17,13 @@ int main(int argc, char** argv) { uint16_t port = 9191; if (argc >= 3) port = atoi(argv[2]); - // connect to TCP socket (automatically spawns thread) - PBSocket sock(addr, port); + try { + // connect to TCP socket (automatically spawns thread) + PBSocket sock(addr, port); + } catch (const std::exception& e) { + printf("error: %s\n", e.what()); + return EXIT_FAILURE; + } // enter main CLI (using GNU readline for comfyness) return cli_main(); diff --git a/client/rl.h b/client/rl.h index 7eef4da..313a8fe 100644 --- a/client/rl.h +++ b/client/rl.h @@ -1,9 +1,9 @@ #pragma once -#define COLOR_OFF "\x1B[0m" -#define COLOR_BLUE "\x1B[0;94m" +#define COLOR_OFF "\x1b[0m" +#define COLOR_BOLD "\x1b[1m" -#define CLI_PROMPT COLOR_BLUE "pbc" COLOR_OFF "% " +#define CLI_PROMPT "(" COLOR_BOLD "pbc" COLOR_OFF ") " #ifdef __cplusplus extern "C" { diff --git a/client/sock.cpp b/client/sock.cpp index 703ee24..17d9e35 100644 --- a/client/sock.cpp +++ b/client/sock.cpp @@ -1,29 +1,86 @@ +#include <arpa/inet.h> +#include <cstring> +#include <stdexcept> #include <unistd.h> #include <cstdio> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <errno.h> #include <thread> #include "sock.h" #include "rl.h" -PBSocket::PBSocket() { - printf("Init PBSocket!\n"); -} +using std::logic_error; +using std::thread; +PBSocket::PBSocket() { } PBSocket::PBSocket(char* addr, uint16_t port) : PBSocket() { - connect(addr, port); + set_server(addr, port); + sock_connect(); +} + +PBSocket::~PBSocket() { + // stop TCP listen thread + if (_thread != nullptr) { + _thread->detach(); + delete _thread; + } + + sock_close(); +} + +void PBSocket::set_server(char* addr, uint16_t port) { + _addr = addr; + _port = port; } -void PBSocket::connect(char* addr, uint16_t port) { - printf("Connect to %s on port %d\n", addr, port); +void PBSocket::sock_connect() { + if (_addr == NULL) throw logic_error("no server address defined"); + if (_port == 0) throw logic_error("no server port defined"); - this->_thread = std::thread(&PBSocket::sock_task, this); + if (_thread != nullptr) throw logic_error("already connected"); + + rl_printf("connecting to %s on port %d...\n", _addr, _port); + + _fd = socket(AF_INET, SOCK_STREAM, 0); + if (_fd < 0) throw logic_error("socket create failed"); + + struct sockaddr_in server = { + .sin_family = AF_INET, + .sin_port = htons(_port), + .sin_addr = { + .s_addr = inet_addr(_addr), + }, + }; + int ret = connect(_fd, (struct sockaddr*) &server, sizeof(server)); + if (ret != 0) throw logic_error(strerror(errno)); + + this->_thread = new thread(&PBSocket::sock_task, this); +} + +void PBSocket::sock_close() { + if (_fd < 0) return; // already closed + close(_fd); + _fd = -1; } void PBSocket::sock_task() { while(1) { - sleep(3); - rl_printf("Testing asynchronous messages in prompt...\n"); + char buf[80]; + ssize_t bytes = read(_fd, buf, sizeof(buf)); + + if (bytes == -1) { + rl_printf("error: %s (%d)\n", strerror(errno), errno); + sock_close(); + break; + } + + if (bytes > 0) { + rl_printf("received %d bytes\n", bytes); + } } } diff --git a/client/sock.h b/client/sock.h index e3d7ec8..0f9a3fc 100644 --- a/client/sock.h +++ b/client/sock.h @@ -5,17 +5,24 @@ class PBSocket { public: + PBSocket(); PBSocket(char* addr, uint16_t port); + virtual ~PBSocket(); - void connect(char* addr, uint16_t port); + void set_server(char* addr, uint16_t port); -private: - PBSocket(); + void sock_connect(); +private: void sock_task(); + void sock_close(); - std::thread _thread; + std::thread* _thread = nullptr; -}; + char* _addr = NULL; + uint16_t _port = 0; + + int _fd = -1; +}; |