Created
October 2, 2023 18:39
-
-
Save abaduser/728be35dd175ae1ba570fe25d5497e1c to your computer and use it in GitHub Desktop.
tcp shared mem writer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <algorithm> | |
#include <cstring> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <unistd.h> | |
#include <thread> | |
#include <sys/mman.h> | |
#include <fcntl.h> | |
#include <sys/stat.h> | |
#include <sys/ipc.h> | |
#include <sys/shm.h> | |
#include <signal.h> | |
#ifdef DEBUG | |
#define HOST htonl(INADDR_LOOPBACK) | |
#else | |
#define HOST INADDR_ANY | |
#endif | |
const int PORT = 65432; | |
const int BUFFER_SIZE = 1024; | |
const key_t SHM_KEY = 12345; | |
void daemonize() { | |
pid_t pid = fork(); | |
if (pid > 0) { | |
exit(0); // Parent exits | |
} | |
chdir("/"); | |
setsid(); | |
umask(0); | |
pid = fork(); | |
if (pid > 0) { | |
exit(0); // Parent exits | |
} | |
#ifdef DEBUG | |
std::cout << "Daemonized process ID: " << getpid() << std::endl; | |
#endif | |
close(STDIN_FILENO); | |
close(STDOUT_FILENO); | |
close(STDERR_FILENO); | |
} | |
void handle_client(int client_fd) { | |
int shm_id = -1; | |
char* ptr = nullptr; | |
int connection_attempts = 0; | |
char buffer[BUFFER_SIZE]; | |
while (true) { | |
if (shm_id == -1) { | |
shm_id = shmget(SHM_KEY, 1, 0666); // Get the shared memory segment | |
if (shm_id == -1) { | |
connection_attempts++; | |
if (connection_attempts >= 10) { | |
send(client_fd, "Max attempts reached. Closing connection.\n", 41, 0); | |
break; | |
} | |
send(client_fd, "Shared memory does not exist. Trying again in 2 seconds...\n", 60, 0); | |
sleep(2); | |
continue; | |
} | |
ptr = (char*) shmat(shm_id, NULL, 0); | |
if (ptr == (char*) -1) { | |
#ifdef DEBUG | |
std::cerr << "Error attaching to shared memory." << std::endl; | |
#endif | |
ptr = nullptr; | |
} | |
connection_attempts = 0; | |
} | |
ssize_t bytes_read = recv(client_fd, buffer, BUFFER_SIZE - 1, 0); // Reduced buffer size by 1 for null termination | |
if (bytes_read <= 0) { // Check for errors or client disconnect | |
if (bytes_read < 0) { | |
#ifdef DEBUG | |
std::cerr << "Error reading from client. Closing connection." << std::endl; | |
#endif | |
} | |
break; | |
} | |
buffer[bytes_read] = '\0'; | |
std::string data(buffer); | |
data.erase(std::remove_if(data.begin(), data.end(), ::isspace), data.end()); | |
if (data == "exit") { | |
break; | |
} | |
if (ptr && (data == "0" || data == "1")) { | |
if (data == "0") { | |
*ptr = 0; | |
} else if (data == "1") { | |
*ptr = 1; | |
} | |
// Check for errors when sending | |
ssize_t bytes_sent = send(client_fd, "Value written to shared memory.\n", 33, 0); | |
if (bytes_sent < 0) { | |
#ifdef DEBUG | |
std::cerr << "Error sending to client. Closing connection." << std::endl; | |
#endif | |
break; | |
} | |
} else { | |
send(client_fd, "Invalid input. Please send 0 or 1.\n", 36, 0); | |
} | |
} | |
if (ptr) { | |
shmdt(ptr); | |
} | |
close(client_fd); | |
} | |
int main() { | |
daemonize(); // Daemonize | |
signal(SIGCHLD, SIG_IGN); | |
signal(SIGPIPE, SIG_IGN); | |
int server_fd = socket(AF_INET, SOCK_STREAM, 0); | |
if (server_fd == -1) { | |
return 1; | |
} | |
sockaddr_in address; | |
address.sin_family = AF_INET; | |
address.sin_addr.s_addr = HOST; | |
address.sin_port = htons(PORT); | |
if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) { | |
return 1; | |
} | |
if (listen(server_fd, 10) < 0) { | |
return 1; | |
} | |
while (true) { | |
int client_fd = accept(server_fd, nullptr, nullptr); | |
if (client_fd < 0) { | |
continue; | |
} | |
std::thread client_thread(handle_client, client_fd); | |
client_thread.detach(); | |
} | |
close(server_fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment