fix server broadcasting demo
This commit is contained in:
@@ -18,7 +18,7 @@ An Accordion server allows clients to view and publish chat messages; authentica
|
|||||||
|
|
||||||
Total running list of external software source packages:
|
Total running list of external software source packages:
|
||||||
- OpenSSL: TLS Networking Security
|
- OpenSSL: TLS Networking Security
|
||||||
- RtMidi: Realtime Audio I/O Processing
|
- RtAudio: Realtime Audio I/O Processing
|
||||||
- libconfig++: Configuration File Interfacing
|
- libconfig++: Configuration File Interfacing
|
||||||
- more to come in the future 🐰
|
- more to come in the future 🐰
|
||||||
Similarly, a list of dependent linux packages:
|
Similarly, a list of dependent linux packages:
|
||||||
@@ -27,7 +27,7 @@ Similarly, a list of dependent linux packages:
|
|||||||
|
|
||||||
## Development plan:
|
## Development plan:
|
||||||
- [x] Build & project setup, get working hello-world program.
|
- [x] Build & project setup, get working hello-world program.
|
||||||
- [ ] TCP Demo between client and server
|
- [x] TCP Demo between client and server
|
||||||
- [ ] Add TLS with OpenSSL on top of the TCP
|
- [ ] Add TLS with OpenSSL on top of the TCP
|
||||||
- [ ] Build and deploy server to a Docker container in a CI/CD pipeline
|
- [ ] Build and deploy server to a Docker container in a CI/CD pipeline
|
||||||
- [ ] Implement PostgreSQL interfacing for the server
|
- [ ] Implement PostgreSQL interfacing for the server
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ ErrorCode TcpClient::init() {
|
|||||||
logger_->log("TcpClient", LogFlag::Debug, "Initializing TcpClient...");
|
logger_->log("TcpClient", LogFlag::Debug, "Initializing TcpClient...");
|
||||||
|
|
||||||
// keeping everything in here for now
|
// keeping everything in here for now
|
||||||
int socketFd; // file descriptor for the client socket (socket proper is a function)
|
|
||||||
int sendBytes;
|
|
||||||
int receiveBytes;
|
int receiveBytes;
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
|
|
||||||
@@ -36,15 +34,15 @@ ErrorCode TcpClient::init() {
|
|||||||
host = gethostbyname(configuration_.hostname.c_str());
|
host = gethostbyname(configuration_.hostname.c_str());
|
||||||
if(host == NULL) {
|
if(host == NULL) {
|
||||||
logger_->log("TcpClient", LogFlag::Debug, "Unable to parse hostname.");
|
logger_->log("TcpClient", LogFlag::Debug, "Unable to parse hostname.");
|
||||||
close(socketFd); // TODO: probably on a destructor
|
close(socketFd_); // TODO: probably on a destructor
|
||||||
return ErrorCode::Error;
|
return ErrorCode::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create tcp socket
|
// create tcp socket
|
||||||
socketFd = socket(AF_INET, SOCK_STREAM, 0);
|
socketFd_ = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if(socketFd < 0) {
|
if(socketFd_ < 0) {
|
||||||
logger_->log("TcpClient", LogFlag::Debug, "Unable to open client socket.");
|
logger_->log("TcpClient", LogFlag::Debug, "Unable to open client socket.");
|
||||||
close(socketFd);
|
close(socketFd_);
|
||||||
return ErrorCode::Error;
|
return ErrorCode::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,31 +53,25 @@ ErrorCode TcpClient::init() {
|
|||||||
serverAddress.sin_addr = *((struct in_addr*)host->h_addr);
|
serverAddress.sin_addr = *((struct in_addr*)host->h_addr);
|
||||||
|
|
||||||
// connect to server
|
// connect to server
|
||||||
if(connect(socketFd, (struct sockaddr*)&serverAddress, sizeof(struct sockaddr)) < 0) {
|
if(connect(socketFd_, (struct sockaddr*)&serverAddress, sizeof(struct sockaddr)) < 0) {
|
||||||
logger_->log("TcpClient", LogFlag::Debug, "Unable to connect to server.");
|
logger_->log("TcpClient", LogFlag::Debug, "Unable to connect to server.");
|
||||||
close(socketFd);
|
close(socketFd_);
|
||||||
return ErrorCode::Error;
|
return ErrorCode::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string message = "placeholder";
|
// start sending thread (only needed for cli because std::cin is blocking. a regular message box doesn't need to block for input)
|
||||||
while(!message.empty()) {
|
pthread_t messengerThread;
|
||||||
logger_->log("TcpClient", LogFlag::Debug, "Enter message...");
|
if(pthread_create(&messengerThread, NULL, TcpClient::sendMessage, static_cast<TcpClient*>(this)) != 0) {
|
||||||
std::getline(std::cin, message);
|
logger_->log("TcpClient", LogFlag::Debug, "Unable to spawn messenger thread.");
|
||||||
|
close(socketFd_);
|
||||||
// send data buffer to server
|
return ErrorCode::Error;
|
||||||
sendBytes = tcpSend(socketFd, message.c_str(), message.size());
|
}
|
||||||
|
|
||||||
if(sendBytes < 0) {
|
|
||||||
logger_->log("TcpClient", LogFlag::Error, "Unable to send to server.");
|
|
||||||
close(socketFd);
|
|
||||||
return ErrorCode::Error;
|
|
||||||
}
|
|
||||||
logger_->log("TcpClient", LogFlag::Debug, "Sent {} bytes to the server.", sendBytes);
|
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
|
||||||
// listen for receive from the server
|
// listen for receive from the server
|
||||||
memset(buffer, 0x00, sizeof(buffer));
|
memset(buffer, 0x00, sizeof(buffer));
|
||||||
receiveBytes = tcpRead(socketFd, buffer, sizeof(buffer)); // TODO: this currently blocks forever, add timeout
|
receiveBytes = tcpRead(socketFd_, buffer, sizeof(buffer)); // TODO: this currently blocks forever, add timeout
|
||||||
// TODO: separate thread
|
// TODO: separate thread
|
||||||
|
|
||||||
// we expect a response based on the server design, something went wrong otherwise
|
// we expect a response based on the server design, something went wrong otherwise
|
||||||
@@ -88,7 +80,7 @@ ErrorCode TcpClient::init() {
|
|||||||
return ErrorCode::Error;
|
return ErrorCode::Error;
|
||||||
} else if(receiveBytes == 0) {
|
} else if(receiveBytes == 0) {
|
||||||
logger_->log("TcpClient", LogFlag::Error, "Server closed the connection during receive.");
|
logger_->log("TcpClient", LogFlag::Error, "Server closed the connection during receive.");
|
||||||
close(socketFd);
|
close(socketFd_);
|
||||||
return ErrorCode::Error;
|
return ErrorCode::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,7 +88,30 @@ ErrorCode TcpClient::init() {
|
|||||||
logger_->log("TcpClient", LogFlag::Debug, "Received {} bytes back from the server: {}", receiveBytes, receivedMessage);
|
logger_->log("TcpClient", LogFlag::Debug, "Received {} bytes back from the server: {}", receiveBytes, receivedMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(socketFd);
|
close(socketFd_);
|
||||||
|
pthread_join(messengerThread, NULL);
|
||||||
|
|
||||||
return ErrorCode::Success;
|
return ErrorCode::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* TcpClient::sendMessage(void* arg) {
|
||||||
|
|
||||||
|
int sendBytes;
|
||||||
|
std::string message = "placeholder";
|
||||||
|
TcpClient* obj = static_cast<TcpClient*>(arg);
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
obj->logger_->log("TcpClient", LogFlag::Debug, "Enter message...");
|
||||||
|
std::getline(std::cin, message);
|
||||||
|
|
||||||
|
// send data buffer to server
|
||||||
|
sendBytes = obj->tcpSend(obj->socketFd_, message.c_str(), message.size());
|
||||||
|
|
||||||
|
if(sendBytes < 0) {
|
||||||
|
obj->logger_->log("TcpClient", LogFlag::Error, "Unable to send to server.");
|
||||||
|
close(obj->socketFd_);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
obj->logger_->log("TcpClient", LogFlag::Debug, "Sent {} bytes to the server.", sendBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/time.h> // TODO replace with chrono
|
#include <sys/time.h> // TODO replace with chrono
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "common/config/ConfigService.hpp"
|
#include "common/config/ConfigService.hpp"
|
||||||
#include "common/LoggerService.hpp"
|
#include "common/LoggerService.hpp"
|
||||||
@@ -25,6 +26,10 @@ private:
|
|||||||
|
|
||||||
ErrorCode init();
|
ErrorCode init();
|
||||||
|
|
||||||
|
// handler for sending messages since std::cin is blocking
|
||||||
|
static void* sendMessage(void* arg);
|
||||||
|
|
||||||
ClientParams configuration_;
|
ClientParams configuration_;
|
||||||
|
int socketFd_; // file descriptor for the client socket (socket proper is a function)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -172,8 +172,10 @@ ErrorCode TcpServer::handleMessage(const char* message, size_t msgLength, uint32
|
|||||||
logger_->log("TcpClient", LogFlag::Debug, "Received {} bytes from client {}: {}",
|
logger_->log("TcpClient", LogFlag::Debug, "Received {} bytes from client {}: {}",
|
||||||
msgLength, clientAddresses[socketId], messageString);
|
msgLength, clientAddresses[socketId], messageString);
|
||||||
|
|
||||||
|
messageString = std::format("{}: {}", clientAddresses[socketId], messageString);
|
||||||
|
|
||||||
// broadcast to all clients
|
// broadcast to all clients
|
||||||
if(broadcastMessage(message, msgLength) != ErrorCode::Success) {
|
if(broadcastMessage(messageString.c_str(), messageString.length()) != ErrorCode::Success) {
|
||||||
logger_->log("TcpServer", LogFlag::Error, "Broadcast failure.");
|
logger_->log("TcpServer", LogFlag::Error, "Broadcast failure.");
|
||||||
return ErrorCode::Error;
|
return ErrorCode::Error;
|
||||||
}
|
}
|
||||||
@@ -183,7 +185,8 @@ ErrorCode TcpServer::handleMessage(const char* message, size_t msgLength, uint32
|
|||||||
|
|
||||||
ErrorCode TcpServer::broadcastMessage(const char* message, size_t msgLength) {
|
ErrorCode TcpServer::broadcastMessage(const char* message, size_t msgLength) {
|
||||||
|
|
||||||
for(size_t i = 1; i < clientCount; i++) {
|
for(size_t i = 1; i <= clientCount; i++) {
|
||||||
|
if(sockets[i].fd == -1) continue;
|
||||||
|
|
||||||
ssize_t sendBytes = tcpSend(sockets[i].fd, message, msgLength);
|
ssize_t sendBytes = tcpSend(sockets[i].fd, message, msgLength);
|
||||||
if(sendBytes != msgLength) {
|
if(sendBytes != msgLength) {
|
||||||
|
|||||||
Reference in New Issue
Block a user