messy client<->server checkpoint
This commit is contained in:
2
.gitea/.workflows/build-and-deploy.yaml
Normal file
2
.gitea/.workflows/build-and-deploy.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
# placeholder
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
add_executable(accordion-client
|
add_executable(accordion-client
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
# other client source files go here
|
# other client source files go here
|
||||||
|
src/TcpClient.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
message(STATUS ${ROOT_DIR})
|
message(STATUS ${ROOT_DIR})
|
||||||
|
|||||||
@@ -19,3 +19,12 @@ Logger = (
|
|||||||
FileName = "app.log";
|
FileName = "app.log";
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TcpClient = (
|
||||||
|
{
|
||||||
|
Id = "main";
|
||||||
|
|
||||||
|
Hostname = "127.0.0.1";
|
||||||
|
Port = 39500;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|||||||
83
client/src/TcpClient.cpp
Normal file
83
client/src/TcpClient.cpp
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
#include "TcpClient.hpp"
|
||||||
|
|
||||||
|
TcpClient::TcpClient(ConfigService* config, LoggerService* logger) : config_(config), logger_(logger) {
|
||||||
|
|
||||||
|
if(!(config->getConfig<ClientConfig>("TcpClient", "main", &configuration_))) {
|
||||||
|
logger_->log("TcpClient", LogFlag::Error, "Failed to get configuration");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(init() == ErrorCode::Success) {
|
||||||
|
logger_->log("TcpClient", LogFlag::Info, "TcpClient initialized.");
|
||||||
|
} else {
|
||||||
|
logger_->log("TcpClient", LogFlag::Error, "TcpClient failed to initialize.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TcpClient::~TcpClient() {
|
||||||
|
// close port
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode TcpClient::init() {
|
||||||
|
logger_->log("TcpClient", LogFlag::Debug, "Initializing TcpClient...");
|
||||||
|
|
||||||
|
// keeping everything in here for now
|
||||||
|
int socketFd;
|
||||||
|
int sendBytes;
|
||||||
|
int receiveBytes;
|
||||||
|
char buffer[1024];
|
||||||
|
|
||||||
|
struct hostent* host;
|
||||||
|
struct sockaddr_in serverAddress;
|
||||||
|
struct timeval timestamp;
|
||||||
|
struct timeval timestampEnd;
|
||||||
|
|
||||||
|
host = gethostbyname(configuration_.hostname.c_str());
|
||||||
|
if(host == NULL) {
|
||||||
|
logger_->log("TcpClient", LogFlag::Debug, "Unable to parse hostname.");
|
||||||
|
return ErrorCode::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
socketFd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if(socketFd < 0) {
|
||||||
|
logger_->log("TcpClient", LogFlag::Debug, "Unable to open client socket.");
|
||||||
|
return ErrorCode::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
serverAddress.sin_family = AF_INET;
|
||||||
|
serverAddress.sin_port = htons(configuration_.port);
|
||||||
|
serverAddress.sin_addr = *((struct in_addr*)host->h_addr);
|
||||||
|
memset(&serverAddress.sin_zero, 0, sizeof(serverAddress.sin_zero));
|
||||||
|
|
||||||
|
if(connect(socketFd, (struct sockaddr*)&serverAddress, sizeof(struct sockaddr)) < 0) {
|
||||||
|
logger_->log("TcpClient", LogFlag::Debug, "Unable to connect to server.");
|
||||||
|
return ErrorCode::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buffer, 0x67, sizeof(buffer));
|
||||||
|
gettimeofday(×tamp, NULL);
|
||||||
|
|
||||||
|
sendBytes = send(socketFd, buffer, sizeof(buffer), 0);
|
||||||
|
if(sendBytes < 0) {
|
||||||
|
logger_->log("TcpClient", LogFlag::Debug, "Unable to send to server.");
|
||||||
|
return ErrorCode::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
gettimeofday(×tampEnd, NULL);
|
||||||
|
|
||||||
|
memset(buffer, 0x00, sizeof(buffer));
|
||||||
|
receiveBytes = recv(socketFd, buffer, sizeof(buffer), 0);
|
||||||
|
if(receiveBytes < 0) {
|
||||||
|
logger_->log("TcpClient", LogFlag::Debug, "Unable to receive from server.");
|
||||||
|
return ErrorCode::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string msg = "Received " + std::to_string(receiveBytes) + " bytes back from server.";
|
||||||
|
logger_->log("TcpClient", LogFlag::Debug, msg);
|
||||||
|
|
||||||
|
close(socketFd);
|
||||||
|
|
||||||
|
return ErrorCode::Success;
|
||||||
|
}
|
||||||
31
client/src/TcpClient.hpp
Normal file
31
client/src/TcpClient.hpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/time.h> // TODO replace with chrono
|
||||||
|
|
||||||
|
#include "common/config/ConfigService.hpp"
|
||||||
|
#include "common/LoggerService.hpp"
|
||||||
|
#include "common/ErrorCodes.hpp"
|
||||||
|
#include "config/ClientConfig.hpp"
|
||||||
|
|
||||||
|
class TcpClient {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TcpClient(ConfigService* config, LoggerService* logger);
|
||||||
|
~TcpClient();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ErrorCode init();
|
||||||
|
|
||||||
|
LoggerService* logger_;
|
||||||
|
ConfigService* config_;
|
||||||
|
ClientParams configuration_;
|
||||||
|
|
||||||
|
};
|
||||||
31
client/src/config/ClientConfig.hpp
Normal file
31
client/src/config/ClientConfig.hpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/config/IConfig.hpp"
|
||||||
|
|
||||||
|
struct ClientParams {
|
||||||
|
std::string id;
|
||||||
|
|
||||||
|
std::string hostname;
|
||||||
|
uint32_t port;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ClientConfig : public IConfig<ClientParams> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
using IConfig<ClientParams>::IConfig;
|
||||||
|
|
||||||
|
bool parseConfig(const libconfig::Setting& setting) override {
|
||||||
|
|
||||||
|
if (!setting.lookupValue("Id", params_->id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
setting.lookupValue("Hostname", params_->hostname);
|
||||||
|
setting.lookupValue("Port", params_->port);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
@@ -2,14 +2,24 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "common/config/ConfigService.hpp"
|
#include "common/config/ConfigService.hpp"
|
||||||
#include "common/config/LoggerConfig.hpp"
|
|
||||||
#include "common/LoggerService.hpp"
|
#include "common/LoggerService.hpp"
|
||||||
|
|
||||||
|
#include "TcpClient.hpp"
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
ConfigService config {"client/config/main.cfg"}; // TODO: main config file should be the foremost cli argument
|
std::string centralConfigPath = "client/config/main.cfg"; // default path
|
||||||
|
if(argc > 1) {
|
||||||
|
centralConfigPath = std::string(argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigService config { centralConfigPath };
|
||||||
LoggerService logger {&config, "main"};
|
LoggerService logger {&config, "main"};
|
||||||
|
|
||||||
logger.log("main", LogFlag::Debug, "hello world from the client!");
|
logger.log("main", LogFlag::Debug, "hello world from the client!");
|
||||||
|
|
||||||
|
TcpClient client {&config, &logger};
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
10
common/ErrorCodes.hpp
Normal file
10
common/ErrorCodes.hpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum class ErrorCode : int {
|
||||||
|
|
||||||
|
Success = 0,
|
||||||
|
Error = -1,
|
||||||
|
// ...
|
||||||
|
|
||||||
|
};
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
add_executable(accordion-server
|
add_executable(accordion-server
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
# other server source files go here
|
# other server source files go here
|
||||||
|
src/TcpServer.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(accordion-server PRIVATE
|
target_include_directories(accordion-server PRIVATE
|
||||||
|
|||||||
@@ -19,3 +19,11 @@ Logger = (
|
|||||||
FileName = "app.log";
|
FileName = "app.log";
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TcpServer = (
|
||||||
|
{
|
||||||
|
Id = "main";
|
||||||
|
|
||||||
|
Port = 39500;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|||||||
0
server/docker-compose.yaml
Normal file
0
server/docker-compose.yaml
Normal file
95
server/src/TcpServer.cpp
Normal file
95
server/src/TcpServer.cpp
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
|
||||||
|
#include "TcpServer.hpp"
|
||||||
|
|
||||||
|
TcpServer::TcpServer(ConfigService* config, LoggerService* logger) : config_(config), logger_(logger) {
|
||||||
|
|
||||||
|
if(!(config->getConfig<ServerConfig>("TcpServer", "main", &configuration_))) {
|
||||||
|
logger_->log("TcpServer", LogFlag::Error, "Failed to get configuration");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(init() == ErrorCode::Success) {
|
||||||
|
logger_->log("TcpServer", LogFlag::Info, "TcpServer initialized.");
|
||||||
|
} else {
|
||||||
|
logger_->log("TcpServer", LogFlag::Error, "TcpServer failed to initialize.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TcpServer::~TcpServer() {
|
||||||
|
// close port
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode TcpServer::init() {
|
||||||
|
logger_->log("TcpServer", LogFlag::Debug, "Initializing TcpServer...");
|
||||||
|
|
||||||
|
// keeping everything in here for now
|
||||||
|
int socketFd;
|
||||||
|
int clientFd;
|
||||||
|
char buffer[1024];
|
||||||
|
int receiveBytes;
|
||||||
|
int sendBytes;
|
||||||
|
|
||||||
|
struct sockaddr_in serverAddress;
|
||||||
|
struct sockaddr_in clientAddress;
|
||||||
|
|
||||||
|
socketFd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if(socketFd < 0) {
|
||||||
|
logger_->log("TcpServer", LogFlag::Error, "Unable to open Server socket.");
|
||||||
|
return ErrorCode::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int on = 1;
|
||||||
|
setsockopt(socketFd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||||
|
|
||||||
|
serverAddress.sin_family = AF_INET;
|
||||||
|
serverAddress.sin_port = htons(configuration_.port);
|
||||||
|
serverAddress.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
memset(&serverAddress.sin_zero, 0, sizeof(serverAddress.sin_zero));
|
||||||
|
|
||||||
|
if(bind(socketFd, (struct sockaddr*)&serverAddress, sizeof(struct sockaddr)) < 0) {
|
||||||
|
logger_->log("TcpServer", LogFlag::Error, "Unable to bind server socket.");
|
||||||
|
return ErrorCode::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(buffer, 0x0, sizeof(buffer));
|
||||||
|
listen(socketFd, 10);
|
||||||
|
logger_->log("TcpServer", LogFlag::Debug, "Server listening...");
|
||||||
|
|
||||||
|
unsigned int sinSize = sizeof(struct sockaddr);
|
||||||
|
clientFd = accept(socketFd, (struct sockaddr*)&clientAddress, &sinSize);
|
||||||
|
if(clientFd < 0) {
|
||||||
|
logger_->log("TcpServer", LogFlag::Error, "Unable to accept client socket.");
|
||||||
|
return ErrorCode::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in peerAddress;
|
||||||
|
unsigned int len = sizeof(peerAddress);
|
||||||
|
char serverIp[20];
|
||||||
|
std::string msg = "Accept socket... Client address: " + std::string(inet_ntoa(clientAddress.sin_addr)) + " Port: " + std::to_string(ntohs(clientAddress.sin_port));
|
||||||
|
logger_->log("TcpServer", LogFlag::Debug, msg);
|
||||||
|
getsockname(clientFd, (struct sockaddr*)&peerAddress, &len);
|
||||||
|
inet_ntop(AF_INET, &peerAddress, serverIp, sizeof(serverIp));
|
||||||
|
msg = "Accept socket... Server address: " + std::string(serverIp);
|
||||||
|
logger_->log("TcpServer", LogFlag::Debug, msg);
|
||||||
|
|
||||||
|
receiveBytes = recv(clientFd, buffer, sizeof(buffer), 0);
|
||||||
|
if(receiveBytes < 0) {
|
||||||
|
logger_->log("TcpServer", LogFlag::Error, "Unable to receive from client.");
|
||||||
|
return ErrorCode::Error;
|
||||||
|
}
|
||||||
|
msg = "Received " + std::to_string(receiveBytes) + " bytes from client: " + std::to_string(buffer[2]);
|
||||||
|
logger_->log("TcpClient", LogFlag::Debug, msg);
|
||||||
|
|
||||||
|
// echo back
|
||||||
|
sendBytes = send(clientFd, buffer, sizeof(buffer), 0);
|
||||||
|
if(sendBytes < 0) {
|
||||||
|
logger_->log("TcpServer", LogFlag::Error, "Unable to send to client.");
|
||||||
|
return ErrorCode::Error;
|
||||||
|
}
|
||||||
|
msg = "Echoed " + std::to_string(sendBytes) + " bytes back to client.";
|
||||||
|
|
||||||
|
close(socketFd);
|
||||||
|
|
||||||
|
return ErrorCode::Success;
|
||||||
|
}
|
||||||
32
server/src/TcpServer.hpp
Normal file
32
server/src/TcpServer.hpp
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/time.h> // TODO replace with chrono
|
||||||
|
|
||||||
|
#include "common/config/ConfigService.hpp"
|
||||||
|
#include "common/LoggerService.hpp"
|
||||||
|
#include "common/ErrorCodes.hpp"
|
||||||
|
#include "config/ServerConfig.hpp"
|
||||||
|
|
||||||
|
class TcpServer {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TcpServer(ConfigService* config, LoggerService* logger);
|
||||||
|
~TcpServer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ErrorCode init();
|
||||||
|
|
||||||
|
LoggerService* logger_;
|
||||||
|
ConfigService* config_;
|
||||||
|
ServerParams configuration_;
|
||||||
|
|
||||||
|
};
|
||||||
29
server/src/config/ServerConfig.hpp
Normal file
29
server/src/config/ServerConfig.hpp
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/config/IConfig.hpp"
|
||||||
|
|
||||||
|
struct ServerParams {
|
||||||
|
std::string id;
|
||||||
|
|
||||||
|
uint32_t port;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ServerConfig : public IConfig<ServerParams> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
using IConfig<ServerParams>::IConfig;
|
||||||
|
|
||||||
|
bool parseConfig(const libconfig::Setting& setting) override {
|
||||||
|
|
||||||
|
if (!setting.lookupValue("Id", params_->id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
setting.lookupValue("Port", params_->port);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
@@ -2,14 +2,24 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "common/config/ConfigService.hpp"
|
#include "common/config/ConfigService.hpp"
|
||||||
#include "common/config/LoggerConfig.hpp"
|
|
||||||
#include "common/LoggerService.hpp"
|
#include "common/LoggerService.hpp"
|
||||||
|
|
||||||
|
#include "TcpServer.hpp"
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
ConfigService config {"server/config/main.cfg"}; // TODO: main config file should be the foremost cli argument
|
std::string centralConfigPath = "server/config/main.cfg"; // default path
|
||||||
|
if(argc > 1) {
|
||||||
|
centralConfigPath = std::string(argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigService config { centralConfigPath };
|
||||||
LoggerService logger {&config, "main"};
|
LoggerService logger {&config, "main"};
|
||||||
|
|
||||||
logger.log("main", LogFlag::Debug, "hello world from the server!");
|
logger.log("main", LogFlag::Debug, "hello world from the Server!");
|
||||||
|
|
||||||
|
TcpServer server {&config, &logger};
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user